mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1131638 - Discard DXVA frames that don't complete YUV->RGB conversion. r=cpearce
This commit is contained in:
parent
4c5a2cdce2
commit
cb8ffc5ee9
@ -33,6 +33,10 @@ void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize,
|
||||
Image* aImage,
|
||||
TimeStamp aTargetTime)
|
||||
{
|
||||
if (!aImage->IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (aIntrinsicSize != mIntrinsicSize) {
|
||||
|
@ -13,10 +13,16 @@
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// Maximum number of ms we're willing to wait for
|
||||
// the YUV -> RGB conversion to take before marking
|
||||
// the texture as invalid.
|
||||
static const uint32_t kMaxWaitSyncMs = 5;
|
||||
|
||||
|
||||
D3D9SurfaceImage::D3D9SurfaceImage()
|
||||
: Image(nullptr, ImageFormat::D3D9_RGB32_TEXTURE)
|
||||
, mSize(0, 0)
|
||||
, mIsValid(true)
|
||||
{}
|
||||
|
||||
D3D9SurfaceImage::~D3D9SurfaceImage()
|
||||
@ -136,9 +142,6 @@ D3D9SurfaceImage::SetData(const Data& aData)
|
||||
hr = device->StretchRect(surface, &src, textureSurface, nullptr, D3DTEXF_NONE);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
// 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.
|
||||
RefPtr<IDirect3DQuery9> query;
|
||||
hr = device->CreateQuery(D3DQUERYTYPE_EVENT, byRef(query));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
@ -148,34 +151,28 @@ D3D9SurfaceImage::SetData(const Data& aData)
|
||||
mTexture = texture;
|
||||
mShareHandle = shareHandle;
|
||||
mSize = gfx::IntSize(region.width, region.height);
|
||||
mQuery = query;
|
||||
|
||||
int iterations = 0;
|
||||
while (true) {
|
||||
HRESULT hr = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
|
||||
if (hr == S_FALSE) {
|
||||
Sleep(1);
|
||||
iterations++;
|
||||
continue;
|
||||
}
|
||||
if (FAILED(hr) || iterations >= kMaxWaitSyncMs) {
|
||||
mIsValid = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void
|
||||
D3D9SurfaceImage::EnsureSynchronized()
|
||||
bool
|
||||
D3D9SurfaceImage::IsValid()
|
||||
{
|
||||
RefPtr<IDirect3DQuery9> query = mQuery;
|
||||
if (!query) {
|
||||
// Not setup, or already synchronized.
|
||||
return;
|
||||
}
|
||||
int iterations = 0;
|
||||
while (iterations < 10 && S_FALSE == query->GetData(nullptr, 0, D3DGETDATA_FLUSH)) {
|
||||
Sleep(1);
|
||||
iterations++;
|
||||
}
|
||||
mQuery = nullptr;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
D3D9SurfaceImage::GetShareHandle()
|
||||
{
|
||||
// Ensure the image has completed its synchronization,
|
||||
// and safe to used by the caller on another device.
|
||||
EnsureSynchronized();
|
||||
return mShareHandle;
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
const D3DSURFACE_DESC&
|
||||
@ -193,7 +190,6 @@ D3D9SurfaceImage::GetSize()
|
||||
TextureClient*
|
||||
D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
EnsureSynchronized();
|
||||
if (!mTextureClient) {
|
||||
RefPtr<SharedTextureClientD3D9> textureClient =
|
||||
new SharedTextureClientD3D9(aClient->GetForwarder(),
|
||||
@ -216,9 +212,6 @@ D3D9SurfaceImage::GetAsSourceSurface()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ensure that the texture is ready to be used.
|
||||
EnsureSynchronized();
|
||||
|
||||
// Readback the texture from GPU memory into system memory, so that
|
||||
// we can copy it into the Cairo image. This is expensive.
|
||||
RefPtr<IDirect3DSurface9> textureSurface;
|
||||
|
@ -41,12 +41,6 @@ public:
|
||||
// Returns the description of the shared surface.
|
||||
const D3DSURFACE_DESC& GetDesc() const;
|
||||
|
||||
// Returns the HANDLE that can be used to open the image as a shared resource.
|
||||
// If the operation to copy the original resource to the shared resource
|
||||
// hasn't finished yet, this function blocks until the synchronization is
|
||||
// complete.
|
||||
HANDLE GetShareHandle();
|
||||
|
||||
gfx::IntSize GetSize() MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
|
||||
@ -54,18 +48,16 @@ public:
|
||||
virtual TextureClient* GetTextureClient(CompositableClient* aClient) MOZ_OVERRIDE;
|
||||
virtual uint8_t* GetBuffer() MOZ_OVERRIDE { return nullptr; }
|
||||
|
||||
private:
|
||||
virtual bool IsValid() MOZ_OVERRIDE;
|
||||
|
||||
// Blocks the calling thread until the copy operation started in SetData()
|
||||
// is complete, whereupon the texture is safe to use.
|
||||
void EnsureSynchronized();
|
||||
private:
|
||||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<IDirect3DTexture9> mTexture;
|
||||
RefPtr<IDirect3DQuery9> mQuery;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
HANDLE mShareHandle;
|
||||
D3DSURFACE_DESC mDesc;
|
||||
bool mIsValid;
|
||||
};
|
||||
|
||||
} // namepace layers
|
||||
|
@ -168,6 +168,8 @@ public:
|
||||
|
||||
virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() = 0;
|
||||
|
||||
virtual bool IsValid() { return true; }
|
||||
|
||||
virtual GrallocImage* AsGrallocImage()
|
||||
{
|
||||
return nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user