]> git.sesse.net Git - vlc/blobdiff - modules/video_output/opengl.c
Direct3D: reject too old drivers and let them fallback to DirectDraw
[vlc] / modules / video_output / opengl.c
index b00157d1660297b12cc1b676dc40c194469c914f..1bbf70b2aacae3fd9ff3090ec0e279636439e8d4 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * opengl.c: OpenGL and OpenGL ES output common code
  *****************************************************************************
- * Copyright (C) 2004 the VideoLAN team
- * Copyright (C) 2009 Laurent Aimar
+ * Copyright (C) 2004-2011 VLC authors and VideoLAN
+ * Copyright (C) 2009, 2011 Laurent Aimar
  *
  * Authors: Cyril Deguet <asmax@videolan.org>
  *          Gildas Bazin <gbazin@videolan.org>
@@ -43,7 +43,7 @@
 # define PFNGLDELETEPROGRAMSARBPROC           typeof(glDeleteProgramsARB)*
 # define PFNGLPROGRAMLOCALPARAMETER4FVARBPROC typeof(glProgramLocalParameter4fvARB)*
 # define PFNGLACTIVETEXTUREARBPROC            typeof(glActiveTextureARB)*
-# define PFNGLMULTITEXCOORD2FARBPROC          typeof(glMultiTexCoord2fARB)*
+# define PFNGLCLIENTACTIVETEXTUREARBPROC      typeof(glClientActiveTextureARB)*
 #endif
 
 /* RV16 */
@@ -57,9 +57,6 @@
 #if USE_OPENGL_ES
 #   define VLCGL_TEXTURE_COUNT 1
 #   define VLCGL_PICTURE_MAX 1
-#elif defined(MACOS_OPENGL)
-#   define VLCGL_TEXTURE_COUNT 2
-#   define VLCGL_PICTURE_MAX 2
 #else
 #   define VLCGL_TEXTURE_COUNT 1
 #   define VLCGL_PICTURE_MAX 128
@@ -121,7 +118,7 @@ struct vout_display_opengl_t {
     /* multitexture */
     bool use_multitexture;
     PFNGLACTIVETEXTUREARBPROC   ActiveTextureARB;
-    PFNGLMULTITEXCOORD2FARBPROC MultiTexCoord2fARB;
+    PFNGLCLIENTACTIVETEXTUREARBPROC ClientActiveTextureARB;
 };
 
 static inline int GetAlignedSize(unsigned size)
@@ -191,13 +188,13 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     if (HasExtension(extensions, "GL_ARB_multitexture")) {
 #if !defined(MACOS_OPENGL)
         vgl->ActiveTextureARB   = (PFNGLACTIVETEXTUREARBPROC)vlc_gl_GetProcAddress(vgl->gl, "glActiveTextureARB");
-        vgl->MultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)vlc_gl_GetProcAddress(vgl->gl, "glMultiTexCoord2fARB");
+        vgl->ClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)vlc_gl_GetProcAddress(vgl->gl, "glClientActiveTextureARB");
 #else
         vgl->ActiveTextureARB = glActiveTextureARB;
-        vgl->MultiTexCoord2fARB = glMultiTexCoord2fARB;
+        vgl->ClientActiveTextureARB = glClientActiveTextureARB;
 #endif
         supports_multitexture = vgl->ActiveTextureARB &&
-                                vgl->MultiTexCoord2fARB;
+                                vgl->ClientActiveTextureARB;
         if (supports_multitexture)
             glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &max_texture_units);
     }
@@ -305,14 +302,14 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
              * by simply changing the coefficients
              */
             const float matrix_bt601_tv2full[3][4] = {
-                { 1.1640,  0.0000,  1.4030, -0.7773 },
-                { 1.1640, -0.3440, -0.7140,  0.4580 },
-                { 1.1640,  1.7730,  0.0000, -0.9630 },
+                { 1.164383561643836,  0.0000,             1.596026785714286, -0.874202217873451 },
+                { 1.164383561643836, -0.391762290094914, -0.812967647237771,  0.531667823499146 },
+                { 1.164383561643836,  2.017232142857142,  0.0000,            -1.085630789302022 },
             };
             const float matrix_bt709_tv2full[3][4] = {
-                { 1.1640,  0.0000,  1.5701, -0.8612 },
-                { 1.1640, -0.1870, -0.4664,  0.2549 },
-                { 1.1640,  1.8556,  0.0000, -1.0045 },
+                { 1.164383561643836,  0.0000,             1.792741071428571, -0.972945075016308 },
+                { 1.164383561643836, -0.21324861427373,  -0.532909328559444,  0.301482665475862 },
+                { 1.164383561643836,  2.112401785714286,  0.0000,            -1.133402217873451 },
             };
             const float (*matrix)[4] = fmt->i_height > 576 ? matrix_bt709_tv2full
                                                            : matrix_bt601_tv2full;
@@ -488,7 +485,7 @@ picture_pool_t *vout_display_opengl_GetPool(vout_display_opengl_t *vgl, unsigned
 
 error:
     for (unsigned i = 0; i < count; i++)
-        picture_Delete(picture[i]);
+        picture_Release(picture[i]);
     return NULL;
 }
 
@@ -516,16 +513,15 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
 
     /* Update the texture */
     for (unsigned j = 0; j < vgl->chroma->plane_count; j++) {
-        const int plane = vgl->fmt.i_chroma == VLC_CODEC_YV12 && j > 0 ?  (3 - j) : j;
         if (vgl->use_multitexture)
             vgl->ActiveTextureARB(GL_TEXTURE0_ARB + j);
         glBindTexture(vgl->tex_target, vgl->texture[0][j]);
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, picture->p[plane].i_pitch / picture->p[plane].i_pixel_pitch);
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, picture->p[j].i_pitch / picture->p[j].i_pixel_pitch);
         glTexSubImage2D(vgl->tex_target, 0,
                         0, 0,
-                        vgl->fmt.i_width  * vgl->chroma->p[plane].w.num / vgl->chroma->p[plane].w.den,
-                        vgl->fmt.i_height * vgl->chroma->p[plane].h.num / vgl->chroma->p[plane].h.den,
-                        vgl->tex_format, vgl->tex_type, picture->p[plane].p_pixels);
+                        vgl->fmt.i_width  * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den,
+                        vgl->fmt.i_height * vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den,
+                        vgl->tex_format, vgl->tex_type, picture->p[j].p_pixels);
     }
 
     int         last_count = vgl->region_count;
@@ -572,13 +568,15 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
                 }
             }
 
+            const int pixels_offset = r->fmt.i_y_offset * r->p_picture->p->i_pitch +
+                                      r->fmt.i_x_offset * r->p_picture->p->i_pixel_pitch;
             if (glr->texture) {
                 glBindTexture(GL_TEXTURE_2D, glr->texture);
                 /* TODO set GL_UNPACK_ALIGNMENT */
                 glPixelStorei(GL_UNPACK_ROW_LENGTH, r->p_picture->p->i_pitch / r->p_picture->p->i_pixel_pitch);
                 glTexSubImage2D(GL_TEXTURE_2D, 0,
                                 0, 0, glr->width, glr->height,
-                                glr->format, glr->type, r->p_picture->p->p_pixels);
+                                glr->format, glr->type, &r->p_picture->p->p_pixels[pixels_offset]);
             } else {
                 glGenTextures(1, &glr->texture);
                 glBindTexture(GL_TEXTURE_2D, glr->texture);
@@ -592,7 +590,7 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
                 glPixelStorei(GL_UNPACK_ROW_LENGTH, r->p_picture->p->i_pitch / r->p_picture->p->i_pixel_pitch);
                 glTexImage2D(GL_TEXTURE_2D, 0, glr->format,
                              glr->width, glr->height, 0, glr->format, glr->type,
-                             r->p_picture->p->p_pixels);
+                             &r->p_picture->p->p_pixels[pixels_offset]);
             }
         }
     }
@@ -671,35 +669,45 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
     glTexCoordPointer(2, GL_FLOAT, 0, textureCoord);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-#else
-    for (unsigned j = 0; j < vgl->chroma->plane_count; j++) {
-        if (vgl->use_multitexture)
-            vgl->ActiveTextureARB(GL_TEXTURE0_ARB + j);
-        glBindTexture(vgl->tex_target, vgl->texture[0][j]);
-    }
-    glBegin(GL_POLYGON);
 
-    glTexCoord2f(left[0],  top[0]);
-    for (unsigned j = 1; j < vgl->chroma->plane_count; j++)
-        vgl->MultiTexCoord2fARB(GL_TEXTURE0_ARB + j, left[j], top[j]);
-    glVertex2f(-1.0,  1.0);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState(GL_VERTEX_ARRAY);
+#else
 
-    glTexCoord2f(right[0], top[0]);
-    for (unsigned j = 1; j < vgl->chroma->plane_count; j++)
-        vgl->MultiTexCoord2fARB(GL_TEXTURE0_ARB + j, right[j], top[j]);
-    glVertex2f( 1.0,  1.0);
+    const GLfloat vertexCoord[] = {
+        -1.0, 1.0,
+        -1.0, -1.0,
+        1.0, 1.0,
+        1.0, -1.0,
+    };
 
-    glTexCoord2f(right[0], bottom[0]);
-    for (unsigned j = 1; j < vgl->chroma->plane_count; j++)
-        vgl->MultiTexCoord2fARB(GL_TEXTURE0_ARB + j, right[j], bottom[j]);
-    glVertex2f( 1.0, -1.0);
+    for( unsigned j = 0; j < vgl->chroma->plane_count; j++)
+    {
+        const GLfloat texCoord[] = {
+            left[j], top[j],
+            left[j], bottom[j],
+            right[j], top[j],
+            right[j], bottom[j],
+        };
+        vgl->ActiveTextureARB( GL_TEXTURE0_ARB+j);
+        vgl->ClientActiveTextureARB( GL_TEXTURE0_ARB+j);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glBindTexture(vgl->tex_target, vgl->texture[0][j]);
+        glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
+    }
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glVertexPointer(2, GL_FLOAT, 0, vertexCoord);
+    glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);
+    glDisableClientState(GL_VERTEX_ARRAY);
+
+    for( int j = vgl->chroma->plane_count; j >= 0;j--)
+    {
+        vgl->ActiveTextureARB( GL_TEXTURE0_ARB+j);
+        vgl->ClientActiveTextureARB( GL_TEXTURE0_ARB+j);
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
 
-    glTexCoord2f(left[0],  bottom[0]);
-    for (unsigned j = 1; j < vgl->chroma->plane_count; j++)
-        vgl->MultiTexCoord2fARB(GL_TEXTURE0_ARB + j, left[j], bottom[j]);
-    glVertex2f(-1.0, -1.0);
 
-    glEnd();
 #endif
 
     if (vgl->program)
@@ -713,29 +721,31 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    const GLfloat textureCoord[] = {
+        0.0, 0.0,
+        0.0, 1.0,
+        1.0, 0.0,
+        1.0, 1.0,
+    };
     for (int i = 0; i < vgl->region_count; i++) {
         gl_region_t *glr = &vgl->region[i];
+        const GLfloat vertexCoord[] = {
+            glr->left, glr->top,
+            glr->left, glr->bottom,
+            glr->right, glr->top,
+            glr->right,glr->bottom,
+        };
+        glColor4f(1.0f, 1.0f, 1.0f, glr->alpha);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
         glBindTexture(GL_TEXTURE_2D, glr->texture);
-
-        glBegin(GL_POLYGON);
-
-        glColor4f(1.0, 1.0, 1.0, glr->alpha);
-
-        glTexCoord2f(0.0, 0.0);
-        glVertex2f(glr->left, glr->top);
-
-        glTexCoord2f(1.0, 0.0);
-        glVertex2f(glr->right, glr->top);
-
-        glTexCoord2f(1.0, 1.0);
-        glVertex2f(glr->right, glr->bottom);
-
-        glTexCoord2f(0.0, 1.0);
-        glVertex2f(glr->left, glr->bottom);
-
-        glEnd();
+        glVertexPointer(2, GL_FLOAT, 0, vertexCoord);
+        glTexCoordPointer(2, GL_FLOAT, 0, textureCoord);
+        glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     }
+    glDisableClientState(GL_VERTEX_ARRAY);
     glDisable(GL_BLEND);
     glDisable(GL_TEXTURE_2D);
 #endif