Skip to content

Commit

Permalink
dxva_egl: flush draw and wait to complete. display is smooth now
Browse files Browse the repository at this point in the history
Without this, display frame rate is right, but pictures are not smooth.
from https://chromium.googlesource.com/chromium/src/+/
ce0e31e88f841148a9acea2609f43cf8a49b631b/content/common/gpu/media/
dxva_video_decode_accelerator.cc
  • Loading branch information
wang-bin committed Jul 9, 2015
1 parent dd294db commit cfa3eca
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
29 changes: 22 additions & 7 deletions src/codec/video/SurfaceInteropDXVA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ class EGL {
EGLInteropResource::EGLInteropResource(IDirect3DDevice9 * d3device)
: InteropResource(d3device)
, egl(new EGL())
, dx_query(NULL)
{
DX_ENSURE_OK(d3device->CreateQuery(D3DQUERYTYPE_EVENT, &dx_query));
dx_query->Issue(D3DISSUE_END);
}

EGLInteropResource::~EGLInteropResource()
Expand All @@ -202,6 +205,7 @@ EGLInteropResource::~EGLInteropResource()
delete egl;
egl = NULL;
}
SafeRelease(&dx_query);
}

void EGLInteropResource::releaseEGL() {
Expand Down Expand Up @@ -297,14 +301,25 @@ bool EGLInteropResource::map(IDirect3DSurface9* surface, GLuint tex, int w, int
}
DYGL(glBindTexture(GL_TEXTURE_2D, tex));
const RECT src = { 0, 0, w, h};
if (SUCCEEDED(d3ddev->StretchRect(surface, &src, dx_surface, NULL, D3DTEXF_NONE)))
if (SUCCEEDED(d3ddev->StretchRect(surface, &src, dx_surface, NULL, D3DTEXF_NONE))) {
if (dx_query) {
// Flush the draw command now. Ideally, this should be done immediately before the draw call that uses the texture. Flush it once here though.
dx_query->Issue(D3DISSUE_END);
// ensure data is copied to egl surface. Solution and comment is from chromium
// The DXVA decoder has its own device which it uses for decoding. ANGLE has its own device which we don't have access to.
// The above code attempts to copy the decoded picture into a surface which is owned by ANGLE.
// As there are multiple devices involved in this, the StretchRect call above is not synchronous.
// We attempt to flush the batched operations to ensure that the picture is copied to the surface owned by ANGLE.
// We need to do this in a loop and call flush multiple times.
// We have seen the GetData call for flushing the command buffer fail to return success occassionally on multi core machines, leading to an infinite loop.
// Workaround is to have an upper limit of 10 on the number of iterations to wait for the Flush to finish.
int k = 0;
while ((dx_query->GetData(NULL, 0, D3DGETDATA_FLUSH) == FALSE) && ++k < 10) {
Sleep(1);
}
}
eglBindTexImage(egl->dpy, egl->surface, EGL_BACK_BUFFER);
// Flush the draw command now, so that by the time we come to draw this
// image, we're less likely to need to wait for the draw operation to
// complete.
//IDirect3DQuery9 *query = NULL;
//DX_ENSURE_OK(d3ddev->CreateQuery(D3DQUERYTYPE_EVENT, &query), false);
//DX_ENSURE_OK(query->Issue(D3DISSUE_END), false);
}
DYGL(glBindTexture(GL_TEXTURE_2D, 0));
return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/codec/video/SurfaceInteropDXVA.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class EGLInteropResource Q_DECL_FINAL: public InteropResource
bool ensureSurface(int w, int h);

EGL* egl;
IDirect3DQuery9 *dx_query;
};
#endif //QTAV_HAVE(DXVA_EGL)

Expand Down

0 comments on commit cfa3eca

Please sign in to comment.