mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 771350, part 2: Use OpenDescriptorForTexturing() in ShadowThebesLayerOGL, where possible. r=BenWa
This commit is contained in:
parent
73a85b798a
commit
708bd2e4ae
@ -27,6 +27,17 @@ using gl::TextureImage;
|
||||
|
||||
static const int ALLOW_REPEAT = ThebesLayerBuffer::ALLOW_REPEAT;
|
||||
|
||||
GLenum
|
||||
WrapMode(GLContext *aGl, PRUint32 aFlags)
|
||||
{
|
||||
if ((aFlags & ALLOW_REPEAT) &&
|
||||
(aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) ||
|
||||
aGl->IsExtensionSupported(GLContext::OES_texture_npot))) {
|
||||
return LOCAL_GL_REPEAT;
|
||||
}
|
||||
return LOCAL_GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
// BindAndDrawQuadWithTextureRect can work with either GL_REPEAT (preferred)
|
||||
// or GL_CLAMP_TO_EDGE textures. If ALLOW_REPEAT is set in aFlags, we
|
||||
// select based on whether REPEAT is valid for non-power-of-two textures --
|
||||
@ -39,15 +50,8 @@ CreateClampOrRepeatTextureImage(GLContext *aGl,
|
||||
TextureImage::ContentType aContentType,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
|
||||
if ((aFlags & ALLOW_REPEAT) &&
|
||||
(aGl->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) ||
|
||||
aGl->IsExtensionSupported(GLContext::OES_texture_npot)))
|
||||
{
|
||||
wrapMode = LOCAL_GL_REPEAT;
|
||||
}
|
||||
|
||||
return aGl->CreateTextureImage(aSize, aContentType, wrapMode);
|
||||
return aGl->CreateTextureImage(aSize, aContentType, WrapMode(aGl, aFlags));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -880,6 +884,11 @@ public:
|
||||
void Upload(gfxASurface* aUpdate, const nsIntRegion& aUpdated,
|
||||
const nsIntRect& aRect, const nsIntPoint& aRotation);
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
Swap(TextureImage* aNewBackBuffer,
|
||||
const nsIntRect& aRect, const nsIntPoint& aRotation,
|
||||
nsIntRect* aPrevRect, nsIntPoint* aPrevRotation);
|
||||
|
||||
protected:
|
||||
virtual nsIntPoint GetOriginOffset() {
|
||||
return mBufferRect.TopLeft() - mBufferRotation;
|
||||
@ -940,6 +949,24 @@ ShadowBufferOGL::Upload(gfxASurface* aUpdate, const nsIntRegion& aUpdated,
|
||||
mBufferRotation = aRotation;
|
||||
}
|
||||
|
||||
already_AddRefed<TextureImage>
|
||||
ShadowBufferOGL::Swap(TextureImage* aNewBackBuffer,
|
||||
const nsIntRect& aRect, const nsIntPoint& aRotation,
|
||||
nsIntRect* aPrevRect, nsIntPoint* aPrevRotation)
|
||||
{
|
||||
nsRefPtr<TextureImage> prevBuffer = mTexImage;
|
||||
*aPrevRect = mBufferRect;
|
||||
*aPrevRotation = mBufferRotation;
|
||||
|
||||
mTexImage = aNewBackBuffer;
|
||||
mBufferRect = aRect;
|
||||
mBufferRotation = aRotation;
|
||||
|
||||
mInitialised = !!mTexImage;
|
||||
|
||||
return prevBuffer.forget();
|
||||
}
|
||||
|
||||
ShadowThebesLayerOGL::ShadowThebesLayerOGL(LayerManagerOGL *aManager)
|
||||
: ShadowThebesLayer(aManager, nsnull)
|
||||
, LayerOGL(aManager)
|
||||
@ -968,22 +995,77 @@ ShadowThebesLayerOGL::Swap(const ThebesBuffer& aNewFront,
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSurfaceDescriptorValid(mBufferDescriptor)) {
|
||||
AutoOpenSurface currentFront(OPEN_READ_ONLY, mBufferDescriptor);
|
||||
AutoOpenSurface newFront(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
if (currentFront.Size() != newFront.Size()) {
|
||||
// The buffer changed size making the current front buffer
|
||||
// obsolete.
|
||||
DestroyFrontBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mBuffer) {
|
||||
mBuffer = new ShadowBufferOGL(this);
|
||||
}
|
||||
AutoOpenSurface frontSurface(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
mBuffer->Upload(frontSurface.Get(), aUpdatedRegion, aNewFront.rect(), aNewFront.rotation());
|
||||
|
||||
if (nsRefPtr<TextureImage> texImage =
|
||||
ShadowLayerManager::OpenDescriptorForDirectTexturing(
|
||||
gl(), aNewFront.buffer(), WrapMode(gl(), ALLOW_REPEAT))) {
|
||||
// We can directly texture the drawn surface. Use that as our new
|
||||
// front buffer, and return our previous directly-textured surface
|
||||
// to the renderer.
|
||||
ThebesBuffer newBack;
|
||||
{
|
||||
nsRefPtr<TextureImage> destroy = mBuffer->Swap(
|
||||
texImage, aNewFront.rect(), aNewFront.rotation(),
|
||||
&newBack.rect(), &newBack.rotation());
|
||||
}
|
||||
newBack.buffer() = mBufferDescriptor;
|
||||
mBufferDescriptor = aNewFront.buffer();
|
||||
|
||||
if (IsSurfaceDescriptorValid(newBack.buffer())) {
|
||||
*aNewBack = newBack;
|
||||
// We have to invalidate the pixels painted into the new buffer.
|
||||
// They might overlap with our old pixels.
|
||||
aNewBackValidRegion->Sub(mValidRegionForNextBackBuffer, aUpdatedRegion);
|
||||
} else {
|
||||
*aNewBack = null_t();
|
||||
aNewBackValidRegion->SetEmpty();
|
||||
}
|
||||
*aReadOnlyFront = aNewFront;
|
||||
*aFrontUpdatedRegion = aUpdatedRegion;
|
||||
} else {
|
||||
// We're using resources owned by our texture as the front buffer.
|
||||
// Upload the changed region and then return the surface back to
|
||||
// the renderer.
|
||||
AutoOpenSurface frontSurface(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
mBuffer->Upload(frontSurface.Get(), aUpdatedRegion, aNewFront.rect(), aNewFront.rotation());
|
||||
|
||||
*aNewBack = aNewFront;
|
||||
*aNewBackValidRegion = mValidRegion;
|
||||
*aReadOnlyFront = null_t();
|
||||
aFrontUpdatedRegion->SetEmpty();
|
||||
*aNewBack = aNewFront;
|
||||
*aNewBackValidRegion = mValidRegion;
|
||||
*aReadOnlyFront = null_t();
|
||||
aFrontUpdatedRegion->SetEmpty();
|
||||
}
|
||||
|
||||
// Save the current valid region of our front buffer, because if
|
||||
// we're double buffering, it's going to be the valid region for the
|
||||
// next back buffer sent back to the renderer.
|
||||
//
|
||||
// NB: we rely here on the fact that mValidRegion is initialized to
|
||||
// empty, and that the first time Swap() is called we don't have a
|
||||
// valid front buffer that we're going to return to content.
|
||||
mValidRegionForNextBackBuffer = mValidRegion;
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerOGL::DestroyFrontBuffer()
|
||||
{
|
||||
mBuffer = nsnull;
|
||||
mValidRegionForNextBackBuffer.SetEmpty();
|
||||
if (IsSurfaceDescriptorValid(mBufferDescriptor)) {
|
||||
mAllocator->DestroySharedSurface(&mBufferDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -138,6 +138,8 @@ public:
|
||||
|
||||
private:
|
||||
nsRefPtr<ShadowBufferOGL> mBuffer;
|
||||
SurfaceDescriptor mBufferDescriptor;
|
||||
nsIntRegion mValidRegionForNextBackBuffer;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
|
Loading…
Reference in New Issue
Block a user