Ticket #9241: mythtv-0.24.diff

File mythtv-0.24.diff, 7.1 KB (added by Lawrence Rust <lvr@…>, 10 years ago)

Direct3D GUI & video fix

  • mythtv/libs/libmythui/mythrender_d3d9.cpp

     
    149149MythRenderD3D9::MythRenderD3D9(void)
    150150  : m_d3d(NULL), m_d3dDevice(NULL),
    151151    m_adaptor_fmt(D3DFMT_UNKNOWN),
    152     m_videosurface_fmt((D3DFORMAT)MAKEFOURCC('Y','V','1','2')),
    153     m_surface_fmt(D3DFMT_A8R8G8B8), m_texture_fmt(D3DFMT_A8R8G8B8),
     152    m_videosurface_fmt(D3DFMT_UNKNOWN),
     153    m_surface_fmt(D3DFMT_UNKNOWN), m_texture_fmt(D3DFMT_A8R8G8B8),
    154154    m_rect_vertexbuffer(NULL), m_default_surface(NULL), m_current_surface(NULL),
    155155    m_lock(QMutex::Recursive),
    156156    m_blend(true), m_multi_texturing(true), m_texture_vertices(true)
     
    196196                                          adaptor, 0, D3DRTYPE_SURFACE, surface);
    197197    if (SUCCEEDED(hr))
    198198    {
     199        // NB CheckDeviceFormatConversion is not fuly implemented in Wine as of 1.3.6
    199200        hr = m_d3d->CheckDeviceFormatConversion(D3DADAPTER_DEFAULT,
    200201                                                D3DDEVTYPE_HAL, surface, adaptor);
    201202        if (SUCCEEDED(hr))
     
    206207
    207208static const QString toString(D3DFORMAT fmt)
    208209{
    209     QString res = "Unknown";
    210210    switch (fmt)
    211211    {
    212212        case D3DFMT_A8:
     
    216216        case D3DFMT_X8R8G8B8:
    217217            return "X8R8G8B8";
    218218        default:
    219             return res;
     219            return QString().setNum((ulong)fmt,16);
    220220    }
    221     return res;
    222221}
    223222
    224223bool MythRenderD3D9::Create(QSize size, HWND window)
     
    228227    typedef LPDIRECT3D9 (WINAPI *LPFND3DC)(UINT SDKVersion);
    229228    static  HINSTANCE hD3DLib            = NULL;
    230229    static  LPFND3DC  OurDirect3DCreate9 = NULL;
    231     D3DCAPS9 d3dCaps;
    232230
    233231    if (!hD3DLib)
    234232    {
     
    256254        return false;
    257255    }
    258256
     257    D3DCAPS9 d3dCaps;
    259258    ZeroMemory(&d3dCaps, sizeof(d3dCaps));
    260259    if (D3D_OK != m_d3d->GetDeviceCaps(
    261260            D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps))
    262261    {
    263262        VERBOSE(VB_IMPORTANT, D3DERR + "Could not read adapter capabilities.");
    264         return false;
    265263    }
    266264
    267265    D3DDISPLAYMODE d3ddm;
     
    271269        return false;
    272270    }
    273271
    274     // TODO - check adaptor format is reasonable and try alternatives
    275272    m_adaptor_fmt = d3ddm.Format;
    276     bool default_ok = FormatSupported(m_videosurface_fmt, m_adaptor_fmt);
    277     if (!default_ok)
    278         m_videosurface_fmt = m_adaptor_fmt;
    279 
    280273    VERBOSE(VB_GENERAL, D3DLOC +
    281         QString("Default Adaptor Format %1 - Hardware YV12 to RGB %2 ")
    282             .arg(toString(m_adaptor_fmt))
    283             .arg(default_ok ? "supported" : "unsupported"));
     274        QString("Default Adaptor Format %1.").arg(toString(m_adaptor_fmt)));
    284275
    285     // TODO - try alternative formats if necessary
    286     if (!FormatSupported(m_surface_fmt, m_adaptor_fmt))
    287         VERBOSE(VB_IMPORTANT, D3DERR + QString("%1 surface format not supported.")
    288                                           .arg(toString(m_surface_fmt)));
     276    // Find the best h/w supported video surface format
     277    static const D3DFORMAT vfmt[] = {
     278        (D3DFORMAT)MAKEFOURCC('Y','V','1','2'),
     279        D3DFMT_UYVY,
     280        D3DFMT_YUY2,
     281        (D3DFORMAT)MAKEFOURCC('I','Y','U','V'),
     282        (D3DFORMAT)MAKEFOURCC('I','4','2','0'),
     283        (D3DFORMAT)MAKEFOURCC('Y','V','1','6'),
     284        D3DFMT_A8R8G8B8,
     285        D3DFMT_X8R8G8B8,
     286        D3DFMT_A8B8G8R8,
     287        D3DFMT_X8B8G8R8
     288    };
     289    for (unsigned i = 0; i < sizeof vfmt / sizeof vfmt[0]; ++i) {
     290        if (SUCCEEDED(m_d3d->CheckDeviceType(D3DADAPTER_DEFAULT,
     291                D3DDEVTYPE_HAL, m_adaptor_fmt, vfmt[i], TRUE))) {
     292            m_videosurface_fmt = vfmt[i];
     293            break;
     294        }
     295    }
     296    if (D3DFMT_UNKNOWN != m_videosurface_fmt)
     297        VERBOSE(VB_GENERAL, D3DLOC +
     298            QString("Best Video Surface Format %1.").arg(toString(m_videosurface_fmt)));
    289299    else
    290         VERBOSE(VB_GENERAL, D3DLOC + QString("Using %1 surface format.")
    291                                           .arg(toString(m_surface_fmt)));
     300        VERBOSE(VB_IMPORTANT, D3DERR + "Failed to agree video surface format");
    292301
     302    // Find the best backing surface format
     303    static const D3DFORMAT bfmt[] = {
     304        D3DFMT_A8R8G8B8,
     305        D3DFMT_X8R8G8B8,
     306        D3DFMT_A8B8G8R8,
     307        D3DFMT_X8B8G8R8,
     308        D3DFMT_R8G8B8
     309    };
     310    for (unsigned i = 0; i < sizeof bfmt / sizeof bfmt[0]; ++i) {
     311        if (FormatSupported(bfmt[i], m_adaptor_fmt)) {
     312            m_surface_fmt = bfmt[i];
     313            break;
     314        }
     315    }
     316    if (D3DFMT_UNKNOWN != m_surface_fmt)
     317        VERBOSE(VB_GENERAL, D3DLOC +
     318            QString("Best surface format: %1.").arg(toString(m_surface_fmt)));
     319    else
     320        VERBOSE(VB_IMPORTANT, D3DERR + "Failed to agree surface format");
     321
    293322    D3DPRESENT_PARAMETERS d3dpp;
    294323    ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
    295     d3dpp.BackBufferFormat       = m_adaptor_fmt;
     324    d3dpp.BackBufferFormat       = m_surface_fmt;
    296325    d3dpp.hDeviceWindow          = window;
    297326    d3dpp.Windowed               = TRUE;
    298327    d3dpp.BackBufferWidth        = size.width();
     
    301330    d3dpp.MultiSampleType        = D3DMULTISAMPLE_NONE;
    302331    d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
    303332    d3dpp.Flags                  = D3DPRESENTFLAG_VIDEO;
    304     d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_ONE;
     333//    d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_ONE;
    305334
    306335    if (D3D_OK != m_d3d->CreateDevice(D3DADAPTER_DEFAULT,
    307                                       D3DDEVTYPE_HAL, d3dpp.hDeviceWindow,
     336                                      D3DDEVTYPE_HAL, NULL,
    308337                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    309338                                      &d3dpp, &m_d3dDevice))
    310339    {
    311340        VERBOSE(VB_IMPORTANT, D3DERR + "Could not create the D3D device.");
    312341        return false;
    313342    }
     343    VERBOSE(VB_GENERAL, D3DLOC + QString("Device backbuffer format: %1.")
     344                                      .arg(toString(d3dpp.BackBufferFormat)));
    314345
     346    if (D3DFMT_UNKNOWN == m_videosurface_fmt)
     347        m_videosurface_fmt = d3dpp.BackBufferFormat;
     348
     349    if (D3DFMT_UNKNOWN == m_surface_fmt)
     350        m_surface_fmt = d3dpp.BackBufferFormat;
     351
    315352    VERBOSE(VB_GENERAL, D3DLOC +
    316353               QString("Hardware YV12 to RGB conversion %1.")
    317354               .arg(m_videosurface_fmt != (D3DFORMAT)MAKEFOURCC('Y','V','1','2') ?
     
    742779        return false;
    743780
    744781    D3DFORMAT format = m_surfaces[surface].m_fmt;
    745     if (format == D3DFMT_A8R8G8B8)
     782    switch (format)
    746783    {
    747         int i;
     784    case D3DFMT_A8R8G8B8:
     785    case D3DFMT_X8R8G8B8:
     786        {
    748787        uint pitch = image->width() << 2;
    749788        uint8_t *dst = buf;
    750789        uint8_t *src = (uint8_t*)image->bits();
    751         for (i = 0; i < image->height(); i++)
     790        for (int i = 0; i < image->height(); i++)
    752791        {
    753792            memcpy(dst, src, pitch);
    754793            dst += d3dpitch;
    755794            src += pitch;
    756         }
    757     }
    758     else
    759     {
     795        }}
     796        break;
     797    default:
    760798        VERBOSE(VB_IMPORTANT, D3DERR + "Surface format not supported.");
     799        break;
    761800    }
    762801
    763802    ReleaseBuffer(surface);