diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 34b573bf2cd..aef61e0fca8 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -39,6 +39,10 @@ typedef char realGLboolean; #include "mozilla/mozalloc.h" +namespace android { +class GraphicBuffer; +} + namespace mozilla { namespace layers { class LayerManagerOGL; @@ -746,6 +750,10 @@ public: virtual bool BindExternalBuffer(GLuint texture, void* buffer) { return false; } virtual bool UnbindExternalBuffer(GLuint texture) { return false; } + virtual already_AddRefed + CreateDirectTextureImage(android::GraphicBuffer* aBuffer, GLenum aWrapMode) + { return nsnull; } + /* * Offscreen support API */ diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index 16abb832c2b..825c3841b09 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -310,7 +310,6 @@ public: } #ifdef MOZ_WIDGET_GONK - gUseBackingSurface = Preferences::GetBool("gfx.gralloc.enabled", false); char propValue[PROPERTY_VALUE_MAX]; property_get("ro.build.version.sdk", propValue, "0"); if (atoi(propValue) < 15) @@ -442,6 +441,11 @@ public: #endif } +#ifdef MOZ_WIDGET_GONK + virtual already_AddRefed + CreateDirectTextureImage(GraphicBuffer* aBuffer, GLenum aWrapMode) MOZ_OVERRIDE; +#endif + bool MakeCurrentImpl(bool aForce = false) { bool succeeded = true; @@ -1204,6 +1208,23 @@ PixelFormatForImage(gfxASurface::gfxImageFormat aFormat) } return 0; } + +static gfxASurface::gfxContentType +ContentTypeForPixelFormat(PixelFormat aFormat) +{ + switch (aFormat) { + case PIXEL_FORMAT_L_8: + return gfxASurface::CONTENT_ALPHA; + case PIXEL_FORMAT_RGBA_8888: + return gfxASurface::CONTENT_COLOR_ALPHA; + case PIXEL_FORMAT_RGBX_8888: + case PIXEL_FORMAT_RGB_565: + return gfxASurface::CONTENT_COLOR; + default: + MOZ_NOT_REACHED("Unknown content type for gralloc pixel format"); + } + return gfxASurface::CONTENT_COLOR; +} #endif static GLenum @@ -1231,7 +1252,8 @@ public: GLenum aWrapMode, ContentType aContentType, GLContext* aContext, - TextureImage::Flags aFlags = TextureImage::NoFlags) + Flags aFlags = TextureImage::NoFlags, + TextureState aTextureState = Created) : TextureImage(aSize, aWrapMode, aContentType, aFlags) , mGLContext(aContext) , mUpdateFormat(gfxASurface::ImageFormatUnknown) @@ -1239,7 +1261,7 @@ public: , mTexture(aTexture) , mSurface(nsnull) , mConfig(nsnull) - , mTextureState(Created) + , mTextureState(aTextureState) , mBound(false) , mIsLocked(false) { @@ -1855,6 +1877,43 @@ protected: } }; +#ifdef MOZ_WIDGET_GONK + +class DirectTextureImageEGL + : public TextureImageEGL +{ +public: + DirectTextureImageEGL(GLuint aTexture, + sp aGraphicBuffer, + GLenum aWrapMode, + GLContext* aContext) + : TextureImageEGL(aTexture, + nsIntSize(aGraphicBuffer->getWidth(), aGraphicBuffer->getHeight()), + aWrapMode, + ContentTypeForPixelFormat(aGraphicBuffer->getPixelFormat()), + aContext, + ForceSingleTile, + Valid) + { + mGraphicBuffer = aGraphicBuffer; + + const int eglImageAttributes[] = + { LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE, + LOCAL_EGL_NONE, LOCAL_EGL_NONE }; + + mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), + EGL_NO_CONTEXT, + EGL_NATIVE_BUFFER_ANDROID, + mGraphicBuffer->getNativeBuffer(), + eglImageAttributes); + if (!mEGLImage) { + LOG("Could not create EGL images: ERROR (0x%04x)", sEGLLibrary.fGetError()); + } + } +}; + +#endif // MOZ_WIDGET_GONK + already_AddRefed GLContextEGL::CreateTextureImage(const nsIntSize& aSize, TextureImage::ContentType aContentType, @@ -1865,6 +1924,30 @@ GLContextEGL::CreateTextureImage(const nsIntSize& aSize, return t.forget(); } +#ifdef MOZ_WIDGET_GONK +already_AddRefed +GLContextEGL::CreateDirectTextureImage(GraphicBuffer* aBuffer, + GLenum aWrapMode) +{ + MakeCurrent(); + + GLuint texture; + fGenTextures(1, &texture); + + nsRefPtr texImage( + new DirectTextureImageEGL(texture, aBuffer, aWrapMode, this)); + texImage->BindTexture(LOCAL_GL_TEXTURE0); + + GLint texfilter = LOCAL_GL_LINEAR; + fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter); + fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter); + fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode); + fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode); + + return texImage.forget(); +} +#endif // MOZ_WIDGET_GONK + already_AddRefed GLContextEGL::TileGenFunc(const nsIntSize& aSize, TextureImage::ContentType aContentType, diff --git a/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp b/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp index dbc3a1c2cea..e87eb05a391 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp +++ b/gfx/layers/ipc/ShadowLayerUtilsD3D10.cpp @@ -75,6 +75,14 @@ ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor*) return false; } +/*static*/ already_AddRefed +ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*, + const SurfaceDescriptor&, + GLenum) +{ + return nsnull; +} + /*static*/ void ShadowLayerManager::PlatformSyncBeforeReplyUpdate() { diff --git a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp index aa0f3f3dcfc..cabed6c9ecd 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp +++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp @@ -170,6 +170,24 @@ GrallocBufferActor::Create(const gfxIntSize& aSize, return actor; } +/*static*/ already_AddRefed +ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext* aGL, + const SurfaceDescriptor& aDescriptor, + GLenum aWrapMode) +{ + if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) { + return nsnull; + } + sp buffer = GrallocBufferActor::GetFrom(aDescriptor); + return aGL->CreateDirectTextureImage(buffer.get(), aWrapMode); +} + +/*static*/ void +ShadowLayerManager::PlatformSyncBeforeReplyUpdate() +{ + // Nothing to be done for gralloc. +} + bool ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface) { @@ -323,8 +341,7 @@ ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescript return false; } - sp buffer = - GrallocBufferActor::GetFrom(aDescriptor); + sp buffer = GrallocBufferActor::GetFrom(aDescriptor); // If the buffer wasn't lock()d, this probably blows up. But since // PlatformCloseDescriptor() is private and only used by // AutoOpenSurface, we want to know if the logic is wrong there. @@ -338,11 +355,5 @@ ShadowLayerForwarder::PlatformSyncBeforeUpdate() // Nothing to be done for gralloc. } -/*static*/ void -ShadowLayerManager::PlatformSyncBeforeReplyUpdate() -{ - // Nothing to be done for gralloc. -} - } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h index 9ff74ecc2a6..d685ad37fac 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h +++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h @@ -60,6 +60,7 @@ class GrallocBufferActor : public PGrallocBufferChild , public PGrallocBufferParent { friend class ShadowLayerForwarder; + friend class ShadowLayerManager; typedef android::GraphicBuffer GraphicBuffer; public: diff --git a/gfx/layers/ipc/ShadowLayerUtilsX11.cpp b/gfx/layers/ipc/ShadowLayerUtilsX11.cpp index abe64c551d9..ef9faf8cf9d 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsX11.cpp +++ b/gfx/layers/ipc/ShadowLayerUtilsX11.cpp @@ -191,6 +191,15 @@ ShadowLayerManager::PlatformSyncBeforeReplyUpdate() } } +/*static*/ already_AddRefed +ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*, + const SurfaceDescriptor&, + GLenum) +{ + // FIXME/bug XXXXXX: implement this using texture-from-pixmap + return nsnull; +} + bool ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface) { diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 84ab57cf53d..4d5a0e2e796 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -557,7 +557,6 @@ ShadowLayerManager::DestroySharedSurface(SurfaceDescriptor* aSurface, } } - #if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS) bool @@ -619,6 +618,14 @@ ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor*) return false; } +/*static*/ already_AddRefed +ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*, + const SurfaceDescriptor&, + GLenum) +{ + return nsnull; +} + /*static*/ void ShadowLayerManager::PlatformSyncBeforeReplyUpdate() { diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 56cfd9ac6e6..6548d823df6 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -9,6 +9,7 @@ #define mozilla_layers_ShadowLayers_h 1 #include "gfxASurface.h" +#include "GLDefs.h" #include "ImageLayers.h" #include "LayersBackend.h" @@ -17,6 +18,13 @@ class gfxSharedImageSurface; namespace mozilla { + +namespace gl { +class GLContext; +class TextureImage; +} +using namespace gl; + namespace layers { class Edit; @@ -402,6 +410,16 @@ public: /** CONSTRUCTION PHASE ONLY */ virtual already_AddRefed CreateShadowRefLayer() { return nsnull; } + /** + * Try to open |aDescriptor| for direct texturing. If the + * underlying surface supports direct texturing, a non-null + * TextureImage is returned. Otherwise null is returned. + */ + static already_AddRefed + OpenDescriptorForDirectTexturing(GLContext* aContext, + const SurfaceDescriptor& aDescriptor, + GLenum aWrapMode); + static void PlatformSyncBeforeReplyUpdate(); void SetCompositorID(PRUint32 aID)