Ticket #2649: opengl_3textures.diff

File opengl_3textures.diff, 13.5 KB (added by mark_kendall@…, 17 years ago)

Use 3 textures for frame upload/colour conversion

  • libs/libmythtv/util-opengl.h

     
    7272                         const QSize &window_size);
    7373
    7474void copy_pixels_to_texture(const unsigned char *buf,
    75                             const int   *offsets,
    7675                            int          buffer_format,
    7776                            const QSize &buffer_size,
    7877                            int          texture,
  • libs/libmythtv/openglvideo.h

     
    9595    OpenGLFilterType GetDeintFilter(void) const;
    9696    bool AddFrameBuffer(uint &framebuffer, uint &texture, QSize size);
    9797    uint AddFragmentProgram(OpenGLFilterType name);
    98     uint CreateVideoTexture(QSize size, QSize &tex_size, bool YUV12);
     98    uint CreateVideoTexture(QSize size, QSize &tex_size);
    9999    QString GetProgramString(OpenGLFilterType filter);
    100100    void CalculateResize(float &left,  float &top,
    101101                         float &right, float &bottom);
  • libs/libmythtv/openglvideo.cpp

     
    134134    if (osd)
    135135    {
    136136        QSize osdsize = visibleRect.size();
     137        QSize half_size(osdsize.width() >> 1, osdsize.height() >>1);
     138        GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize);
     139        GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
     140        GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
     141        GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize);
    137142
    138         GLuint alphatex = CreateVideoTexture(
    139             osdsize, inputTextureSize,
    140             gl_context->IsFeatureSupported(kGLExtRect) ? false : true);
    141 
    142         GLuint yuv12tex = CreateVideoTexture(osdsize, inputTextureSize, true);
    143 
    144         if ((alphatex && yuv12tex) && AddFilter(kGLFilterYUV2RGBA))
     143    if ((alphatex && ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGBA))
    145144        {
    146             inputTextures.push_back(yuv12tex);
     145            inputTextures.push_back(ytex);
     146            inputTextures.push_back(utex);
     147            inputTextures.push_back(vtex);
    147148            inputTextures.push_back(alphatex);
    148149        }
    149150    }
    150151    else
    151152    {
    152         GLuint yuv12tex = CreateVideoTexture(
    153             videoSize, inputTextureSize, true);
     153        QSize half_size(videoSize.width() >> 1, videoSize.height() >>1);
     154        GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
     155        GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
     156        GLuint ytex = CreateVideoTexture(videoSize, inputTextureSize);;
    154157
    155         if (yuv12tex && AddFilter(kGLFilterYUV2RGB))
    156             inputTextures.push_back(yuv12tex);
     158        if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB))
     159        {
     160            inputTextures.push_back(ytex);
     161            inputTextures.push_back(utex);
     162            inputTextures.push_back(vtex);
     163        }
    157164    }
    158165
    159166    if (filters.empty())
     
    169176                "Falling back to software conversion.\n\t\t\t"
    170177                "Any opengl filters will also be disabled.");
    171178
    172         GLuint yuv12tex = CreateVideoTexture(
    173             videoSize, inputTextureSize, false);
     179        GLuint rgb24tex = CreateVideoTexture(videoSize, inputTextureSize);
    174180
    175         if (yuv12tex && AddFilter(kGLFilterResize))
     181        if (rgb24tex && AddFilter(kGLFilterResize))
    176182        {
    177             inputTextures.push_back(yuv12tex);
     183            inputTextures.push_back(rgb24tex);
    178184        }
    179185        else
    180186        {
     
    377383
    378384    temp->numInputs = 1;
    379385
    380     if ((filter == kGLFilterYUV2RGBA) ||
    381         (filter == kGLFilterLinearBlendDeint) ||
     386    if ((filter == kGLFilterLinearBlendDeint) ||
    382387        (filter == kGLFilterKernelDeint))
    383388    {
    384389        temp->numInputs = 2;
    385390    }
    386     else if ((filter == kGLFilterOneFieldDeintDFR) ||
     391    else if ((filter == kGLFilterYUV2RGB) ||
     392             (filter == kGLFilterOneFieldDeintDFR) ||
    387393             (filter == kGLFilterKernelDeintDFR) ||
    388394             (filter == kGLFilterLinearBlendDeintDFR))
    389395    {
    390396        temp->numInputs = 3;
    391397    }
     398    else if ((filter == kGLFilterYUV2RGBA))
     399    {
     400        temp->numInputs = 4;
     401    }
    392402
    393403    GLuint program = 0;
    394404    if (filter != kGLFilterNone && filter != kGLFilterResize)
     
    551561}
    552562
    553563// locking ok
    554 uint OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size, bool YUV12)
     564uint OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size)
    555565{
    556566    uint tmp_tex = gl_context->CreateTexture();
    557567
    558568    QSize temp = GetTextureSize(size);
    559569
    560     if (YUV12)
    561     {
    562         if (gl_context->IsFeatureSupported(kGLExtRect))
    563         {
    564             temp.rheight() = size.height() * 3 / 2;
    565         }
    566         else
    567         {
    568             if ((size.height() * 1.5) > temp.height())
    569                 temp.rheight() *= 2;
    570         }
    571     }
    572 
    573570    if ((temp.width()  > (int)gl_context->GetMaxTexSize()) ||
    574571        (temp.height() > (int)gl_context->GetMaxTexSize()) ||
    575572        !gl_context->SetupTexture(temp, tmp_tex, GL_LINEAR))
     
    669666        return;
    670667
    671668    copy_pixels_to_texture(
    672         buf, offsets, format, size,
     669        buf + offsets[0], format, size,
    673670        inputTextures[texture_index], gl_context->GetTextureType());
    674671
     672    if (FMT_YV12 == format)
     673    {
     674        QSize chroma_size(size.width() >> 1, size.height() >> 1);
     675        copy_pixels_to_texture(
     676            buf + offsets[1], format, chroma_size,
     677            inputTextures[texture_index + 1],
     678            gl_context->GetTextureType());
     679        copy_pixels_to_texture(
     680            buf + offsets[2], format, chroma_size,
     681            inputTextures[texture_index + 2],
     682            gl_context->GetTextureType());
     683    }
     684
    675685    inputUpdated = true;
    676686}
    677687
     
    826836            t_bottom /= inputsize.height();
    827837        }
    828838
    829         float full_height = t_bottom;
    830839        float line_height = (t_bottom / (float)videoSize.height());
    831840        float bob = line_height / 2.0f;
    832841
     
    862871            }
    863872        }
    864873
     874        float t_right_uv = t_right / 2.0f;
     875        float t_top_uv   = t_top / 2.0f;
     876        float t_bottom_uv = t_bottom / 2.0f;
     877
    865878        // vertex coordinates
    866879        QRect display = (filter->outputBuffer == kDefaultBuffer) ?
    867880            videoRect : frameBufferRect;
     
    931944            {
    932945                case kGLFilterYUV2RGB:
    933946                case kGLFilterYUV2RGBA:
    934                     gl_context->InitFragmentParams(
    935                         1, t_right / 2.0f, full_height, 0.0f, 0.0f);
    936 
    937947                    if (useColourControl)
    938948                    {
    939949                        gl_context->InitFragmentParams(
     
    973983
    974984        // draw quad
    975985        glBegin(GL_QUADS);
    976         glTexCoord2f(0.0f,    t_top);    glVertex2f(vleft,  vtop);
    977         glTexCoord2f(t_right, t_top);    glVertex2f(vright, vtop);
    978         glTexCoord2f(t_right, t_bottom); glVertex2f(vright, vbot);
    979         glTexCoord2f(0.0f,    t_bottom); glVertex2f(vleft,  vbot);
     986        glTexCoord2f(0.0f, t_top);
     987        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     988        {
     989            glMultiTexCoord2f(GL_TEXTURE1, 0.0f, t_top_uv);
     990            glMultiTexCoord2f(GL_TEXTURE2, 0.0f, t_top_uv);
     991            if (type == kGLFilterYUV2RGBA)
     992                glMultiTexCoord2f(GL_TEXTURE3, 0.0f, t_top_uv);
     993        }
     994        glVertex2f(vleft,  vtop);
     995
     996        glTexCoord2f(t_right, t_top);
     997        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     998        {
     999            glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_top_uv);
     1000            glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_top_uv);
     1001            if (type == kGLFilterYUV2RGBA)
     1002                glMultiTexCoord2f(GL_TEXTURE3, t_right, t_top);
     1003        }
     1004        glVertex2f(vright, vtop);
     1005
     1006        glTexCoord2f(t_right, t_bottom);
     1007        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     1008        {
     1009            glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_bottom_uv);
     1010            glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_bottom_uv);
     1011            if (type == kGLFilterYUV2RGBA)
     1012                glMultiTexCoord2f(GL_TEXTURE3, t_right, t_bottom);
     1013        }
     1014        glVertex2f(vright, vbot);
     1015
     1016        glTexCoord2f(0.0f, t_bottom);
     1017        if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     1018        {
     1019            glMultiTexCoord2f(GL_TEXTURE1, 0.0f, t_bottom_uv);
     1020            glMultiTexCoord2f(GL_TEXTURE2, 0.0f, t_bottom_uv);
     1021            if (type == kGLFilterYUV2RGBA)
     1022                glMultiTexCoord2f(GL_TEXTURE3, 0.0f, t_bottom);
     1023        }
     1024        glVertex2f(vleft,  vbot);
    9801025        glEnd();
    9811026
    9821027        // disable blending
     
    10921137}
    10931138
    10941139static const QString yuv2rgb1a =
    1095 "ATTRIB ytex = fragment.texcoord[0];"
    1096 "PARAM  off  = program.env[1];"
    1097 "TEMP res, tmp, tmp2;";
     1140"ATTRIB ytex  = fragment.texcoord[0];"
     1141"ATTRIB uvtex = fragment.texcoord[1];"
     1142"TEMP res, tmp;";
    10981143
    10991144static const QString yuv2rgb1b =
    11001145"TEMP alpha;"
    1101 "TEX alpha, ytex, texture[1], %1;";
     1146"TEX alpha, ytex, texture[3], %1;";
    11021147
    11031148static const QString yuv2rgb1c =
    1104 "TEX res, ytex, texture[0], %1;"
    1105 "MAD tmp2, ytex, {0.5, 0.5}, off.wyww;"
    1106 "TEX tmp.x, tmp2, texture[0], %1;"
    1107 "ADD tmp2, tmp2, off.xwww;"
    1108 "TEX tmp.y, tmp2, texture[0], %1;";
     1149"TEX res,   ytex,  texture[0], %1;"
     1150"TEX tmp.x, uvtex, texture[1], %1;"
     1151"TEX tmp.y, uvtex, texture[2], %1;";
    11091152
    11101153static const QString yuv2rgb2 =
    11111154"PARAM  adj  = program.env[0];"
  • libs/libmythtv/xvmctextures.cpp

     
    199199    glTexParameterf(rect_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    200200    glTexParameterf(rect_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    201201
    202     int offset = 0;
    203     copy_pixels_to_texture(pixels, &offset, FMT_RGBA32, gl_video_size,
     202    copy_pixels_to_texture(pixels, FMT_RGBA32, gl_video_size,
    204203                           gl_osd_textures[gl_osd_tex_index], rect_type);
    205204
    206205    glXMakeContextCurrent(XJ_disp, None, None, NULL);
  • libs/libmythtv/util-opengl.cpp

     
    242242}                       
    243243
    244244void copy_pixels_to_texture(const unsigned char *buf,
    245                             const int           *offsets,
    246245                            int                  buffer_format,
    247246                            const QSize         &buffer_size,
    248247                            int                  texture,
     
    250249{
    251250    glBindTexture(texture_type, texture);
    252251
    253     if (FMT_YV12 == buffer_format)
     252    uint format;
     253    switch (buffer_format)
    254254    {
    255         glTexSubImage2D(
    256             texture_type,
    257             0, 0, 0,
    258             buffer_size.width(), buffer_size.height(),
    259             GL_LUMINANCE, GL_UNSIGNED_BYTE,
    260             buf + offsets[0]);
    261 
    262         glTexSubImage2D(
    263             texture_type,
    264             0, 0, buffer_size.height(),
    265             buffer_size.width()>>1, buffer_size.height()>>1,
    266             GL_LUMINANCE, GL_UNSIGNED_BYTE,
    267             buf + offsets[1]);
    268 
    269         glTexSubImage2D(
    270             texture_type,
    271             0, buffer_size.width()>>1, buffer_size.height(),
    272             buffer_size.width()>>1, buffer_size.height()>>1,
    273             GL_LUMINANCE, GL_UNSIGNED_BYTE,
    274             buf + offsets[2]);
     255        case FMT_YV12:
     256            format = GL_LUMINANCE;
     257            break;
     258        case FMT_RGB24:
     259            format = GL_RGB;
     260            break;
     261        case FMT_RGBA32:
     262            format = GL_RGBA;
     263            break;
     264        case FMT_ALPHA:
     265            format = GL_ALPHA;
     266            break;
     267        default:
     268            return;
    275269    }
    276     else if (FMT_RGB24 == buffer_format)
    277     {
    278         glTexSubImage2D(
    279             texture_type, 0, 0, 0,
    280             buffer_size.width(), buffer_size.height(),
    281             GL_RGB, GL_UNSIGNED_BYTE,
    282             buf + offsets[0]);
    283     }
    284     else if (FMT_RGBA32 == buffer_format)
    285     {
    286         glTexSubImage2D(
    287             texture_type, 0, 0, 0,
    288             buffer_size.width(), buffer_size.height(),
    289             GL_RGBA, GL_UNSIGNED_BYTE,
    290             buf + offsets[0]);
    291     }
    292     else if (FMT_ALPHA == buffer_format)
    293     {
    294         glTexSubImage2D(
    295             texture_type, 0, 0, 0,
    296             buffer_size.width(), buffer_size.height(),
    297             GL_ALPHA, GL_UNSIGNED_BYTE,
    298             buf + offsets[0]);
    299     }
     270    glTexSubImage2D(
     271        texture_type,
     272        0, 0, 0,
     273        buffer_size.width(), buffer_size.height(),
     274        format, GL_UNSIGNED_BYTE,
     275        buf);
    300276}
    301277
    302278__GLXextFuncPtr get_gl_proc_address(const QString &procName)
  • libs/libmythtv/videoout_xv.cpp

     
    39583958        gl_osdchain->UpdateInput(surface->yuvbuffer, offsets,
    39593959                                 0, FMT_YV12, visible);
    39603960        gl_osdchain->UpdateInput(surface->alpha, offsets,
    3961                                  1, FMT_ALPHA, visible);
     3961                                 3, FMT_ALPHA, visible);
    39623962    }
    39633963    return changed;
    39643964}