mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 875211 - use one global gl texture per texture unit rather than one per GrallocTextureHostOGL. r=bjacob
This commit is contained in:
parent
bf470038f5
commit
11575bb513
@ -232,6 +232,7 @@ CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth,
|
||||
, mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
|
||||
, mHasBGRA(0)
|
||||
, mUseExternalSurfaceSize(aUseExternalSurfaceSize)
|
||||
, mTextures({0, 0, 0})
|
||||
, mFrameInProgress(false)
|
||||
, mDestroyed(false)
|
||||
{
|
||||
@ -279,9 +280,29 @@ CompositorOGL::AddPrograms(ShaderProgramType aType)
|
||||
}
|
||||
}
|
||||
|
||||
GLuint
|
||||
CompositorOGL::GetTemporaryTexture(GLenum aTextureUnit)
|
||||
{
|
||||
if (!mTextures[aTextureUnit - LOCAL_GL_TEXTURE0]) {
|
||||
gl()->MakeCurrent();
|
||||
gl()->fGenTextures(1, &mTextures[aTextureUnit - LOCAL_GL_TEXTURE0]);
|
||||
}
|
||||
return mTextures[aTextureUnit - LOCAL_GL_TEXTURE0];
|
||||
}
|
||||
|
||||
void
|
||||
CompositorOGL::Destroy()
|
||||
{
|
||||
if (gl()) {
|
||||
gl()->MakeCurrent();
|
||||
gl()->fDeleteTextures(3, mTextures);
|
||||
mTextures[0] = 0;
|
||||
mTextures[1] = 0;
|
||||
mTextures[2] = 0;
|
||||
} else {
|
||||
MOZ_ASSERT(!mTextures[0] && !mTextures[1] && !mTextures[2]);
|
||||
}
|
||||
|
||||
if (!mDestroyed) {
|
||||
mDestroyed = true;
|
||||
CleanupResources();
|
||||
|
@ -134,6 +134,13 @@ public:
|
||||
gl::RGBARectLayerProgramType : gl::RGBALayerProgramType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The compositor provides with temporary textures for use with direct
|
||||
* textruing like gralloc texture.
|
||||
* Doing so lets us use gralloc the way it has been designed to be used
|
||||
* (see https://wiki.mozilla.org/Platform/GFX/Gralloc)
|
||||
*/
|
||||
GLuint GetTemporaryTexture(GLenum aUnit);
|
||||
private:
|
||||
/**
|
||||
* Context target, nullptr when drawing directly to our swap chain.
|
||||
@ -319,6 +326,9 @@ private:
|
||||
bool mDestroyed;
|
||||
|
||||
nsAutoPtr<FPSState> mFPS;
|
||||
// Textures used for direct texturing of buffers like gralloc.
|
||||
// The index of the texture in this array must correspond to the texture unit.
|
||||
GLuint mTextures[3];
|
||||
static bool sDrawFPS;
|
||||
static bool sFrameCounter;
|
||||
};
|
||||
|
@ -700,28 +700,29 @@ TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
|
||||
}
|
||||
}
|
||||
|
||||
GrallocTextureHostOGL::GrallocTextureHostOGL()
|
||||
: mCompositor(nullptr)
|
||||
, mTextureTarget(0)
|
||||
, mEGLImage(0)
|
||||
{
|
||||
}
|
||||
|
||||
void GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
if (mGL && !glCompositor) {
|
||||
if (mCompositor && !glCompositor) {
|
||||
DeleteTextures();
|
||||
}
|
||||
mGL = glCompositor ? glCompositor->gl() : nullptr;
|
||||
mCompositor = glCompositor;
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::DeleteTextures()
|
||||
{
|
||||
if (mGLTexture || mEGLImage) {
|
||||
mGL->MakeCurrent();
|
||||
if (mGLTexture) {
|
||||
mGL->fDeleteTextures(1, &mGLTexture);
|
||||
mGLTexture = 0;
|
||||
}
|
||||
if (mEGLImage) {
|
||||
mGL->DestroyEGLImage(mEGLImage);
|
||||
mEGLImage = 0;
|
||||
}
|
||||
if (mEGLImage) {
|
||||
gl()->MakeCurrent();
|
||||
gl()->DestroyEGLImage(mEGLImage);
|
||||
mEGLImage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -767,20 +768,43 @@ GrallocTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImage,
|
||||
RegisterTextureHostAtGrallocBufferActor(this, aImage);
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
GrallocTextureHostOGL::gl() const
|
||||
{
|
||||
return mCompositor ? mCompositor->gl() : nullptr;
|
||||
}
|
||||
|
||||
void GrallocTextureHostOGL::BindTexture(GLenum aTextureUnit)
|
||||
{
|
||||
MOZ_ASSERT(mGLTexture);
|
||||
/*
|
||||
* The job of this function is to ensure that the texture is tied to the
|
||||
* android::GraphicBuffer, so that texturing will source the GraphicBuffer.
|
||||
*
|
||||
* To this effect we create an EGLImage wrapping this GraphicBuffer,
|
||||
* using CreateEGLImageForNativeBuffer, and then we tie this EGLImage to our
|
||||
* texture using fEGLImageTargetTexture2D.
|
||||
*
|
||||
* We try to avoid re-creating the EGLImage everytime, by keeping it around
|
||||
* as the mEGLImage member of this class.
|
||||
*/
|
||||
MOZ_ASSERT(gl());
|
||||
gl()->MakeCurrent();
|
||||
|
||||
mGL->MakeCurrent();
|
||||
mGL->fActiveTexture(aTextureUnit);
|
||||
mGL->fBindTexture(mTextureTarget, mGLTexture);
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
|
||||
|
||||
gl()->fActiveTexture(aTextureUnit);
|
||||
gl()->fBindTexture(mTextureTarget, tex);
|
||||
if (!mEGLImage) {
|
||||
mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
|
||||
}
|
||||
gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
}
|
||||
|
||||
bool
|
||||
GrallocTextureHostOGL::IsValid() const
|
||||
{
|
||||
return !!mGL && !!mGraphicBuffer.get();
|
||||
return !!gl() && !!mGraphicBuffer.get();
|
||||
}
|
||||
|
||||
GrallocTextureHostOGL::~GrallocTextureHostOGL()
|
||||
@ -798,65 +822,14 @@ GrallocTextureHostOGL::~GrallocTextureHostOGL()
|
||||
bool
|
||||
GrallocTextureHostOGL::Lock()
|
||||
{
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* The job of this function is to ensure that the texture is tied to the
|
||||
* android::GraphicBuffer, so that texturing will source the GraphicBuffer.
|
||||
*
|
||||
* To this effect we create an EGLImage wrapping this GraphicBuffer,
|
||||
* using CreateEGLImageForNativeBuffer, and then we tie this EGLImage to our
|
||||
* texture using fEGLImageTargetTexture2D.
|
||||
*
|
||||
* We try to avoid re-creating the EGLImage everytime, by keeping it around
|
||||
* as the mEGLImage member of this class.
|
||||
*/
|
||||
MOZ_ASSERT(mGraphicBuffer.get());
|
||||
|
||||
mGL->MakeCurrent();
|
||||
|
||||
if (!mGLTexture) {
|
||||
mGL->fGenTextures(1, &mGLTexture);
|
||||
}
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
mGL->fBindTexture(mTextureTarget, mGLTexture);
|
||||
if (!mEGLImage) {
|
||||
mEGLImage = mGL->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
|
||||
}
|
||||
mGL->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
|
||||
return true;
|
||||
// Lock/Unlock is done internally when binding the gralloc buffer to a gl texture
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureHostOGL::Unlock()
|
||||
{
|
||||
/*
|
||||
* The job of this function is to ensure that we release any read lock placed on
|
||||
* our android::GraphicBuffer by any drawing code that sourced it via this TextureHost.
|
||||
*
|
||||
* Indeed, as soon as we draw with a texture that's tied to a android::GraphicBuffer,
|
||||
* the GL may place read locks on it. We must ensure that we release them early enough,
|
||||
* i.e. before the next time that we will try to acquire a write lock on the same buffer,
|
||||
* because read and write locks on gralloc buffers are mutually exclusive.
|
||||
*/
|
||||
if (mGL->Renderer() == GLContext::RendererAdrenoTM205) {
|
||||
/* XXX This is working around a driver bug exhibited on at least the
|
||||
* Geeksphone Peak, where retargeting to a different EGL image is very
|
||||
* slow. See Bug 869696.
|
||||
*/
|
||||
if (mGLTexture) {
|
||||
mGL->MakeCurrent();
|
||||
mGL->fDeleteTextures(1, &mGLTexture);
|
||||
mGLTexture = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mGL->MakeCurrent();
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
mGL->fBindTexture(mTextureTarget, mGLTexture);
|
||||
mGL->fEGLImageTargetTexture2D(mTextureTarget, mGL->GetNullEGLImage());
|
||||
// Lock/Unlock is done internally when binding the gralloc buffer to a gl texture
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
@ -877,7 +850,7 @@ GrallocTextureHostOGL::SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator*
|
||||
RegisterTextureHostAtGrallocBufferActor(this, *mBuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // MOZ_WIDGET_GONK
|
||||
|
||||
already_AddRefed<gfxImageSurface>
|
||||
TextureImageTextureHostOGL::GetAsSurface() {
|
||||
@ -932,10 +905,20 @@ TiledTextureHostOGL::GetAsSurface() {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
already_AddRefed<gfxImageSurface>
|
||||
GrallocTextureHostOGL::GetAsSurface() {
|
||||
nsRefPtr<gfxImageSurface> surf = IsValid() && mGLTexture ?
|
||||
mGL->GetTexImage(mGLTexture,
|
||||
false,
|
||||
GetShaderProgram())
|
||||
gl()->MakeCurrent();
|
||||
|
||||
GLuint tex = mCompositor->GetTemporaryTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
gl()->fBindTexture(mTextureTarget, tex);
|
||||
if (!mEGLImage) {
|
||||
mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
|
||||
}
|
||||
gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = IsValid() ?
|
||||
gl()->GetTexImage(tex,
|
||||
false,
|
||||
GetShaderProgram())
|
||||
: nullptr;
|
||||
return surf.forget();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class TextureImageTextureHostOGL;
|
||||
class CompositorOGL;
|
||||
|
||||
/*
|
||||
* TextureHost implementations for the OpenGL backend.
|
||||
@ -568,23 +569,12 @@ class GrallocTextureHostOGL
|
||||
, public TextureSourceOGL
|
||||
{
|
||||
public:
|
||||
GrallocTextureHostOGL()
|
||||
: mGL(nullptr)
|
||||
, mTextureTarget(0)
|
||||
, mGLTexture(0)
|
||||
, mEGLImage(0)
|
||||
{
|
||||
}
|
||||
GrallocTextureHostOGL();
|
||||
|
||||
~GrallocTextureHostOGL();
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual GLuint GetTextureHandle()
|
||||
{
|
||||
return mGLTexture;
|
||||
}
|
||||
|
||||
virtual void UpdateImpl(const SurfaceDescriptor& aImage,
|
||||
nsIntRegion* aRegion = nullptr,
|
||||
nsIntPoint* aOffset = nullptr) MOZ_OVERRIDE;
|
||||
@ -652,12 +642,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
void DeleteTextures();
|
||||
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
android::sp<android::GraphicBuffer> mGraphicBuffer;
|
||||
GLenum mTextureTarget;
|
||||
GLuint mGLTexture;
|
||||
EGLImage mEGLImage;
|
||||
};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user