author | Ed Morley <emorley@mozilla.com> |
Tue, 10 Jul 2012 16:06:42 +0100 | |
changeset 98823 | 04dc0717dd53724a5e3ed9e07bc38dcd40725b78 |
parent 98822 | 46b33c04a8401194f5e058e467ff03b60aab7008 |
child 98824 | 301b36379f402b4cc91440e5af0c77a4609e2420 |
child 98935 | 340764f48ed218896d47356a3d0d2ed8dc4bc325 |
push id | 11666 |
push user | emorley@mozilla.com |
push date | Tue, 10 Jul 2012 15:07:38 +0000 |
treeherder | mozilla-inbound@04dc0717dd53 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 728524, 772405 |
milestone | 16.0a1 |
backs out | 6087689a07456e521903ce175ab8343cc6b4e9ad |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -42,17 +42,16 @@ namespace mozilla { namespace layers { class LayerManagerOGL; class ColorTextureLayerProgram; } namespace gl { class GLContext; -typedef uintptr_t SharedTextureHandle; enum ShaderProgramType { RGBALayerProgramType, BGRALayerProgramType, RGBXLayerProgramType, BGRXLayerProgramType, RGBARectLayerProgramType, ColorLayerProgramType, @@ -94,21 +93,16 @@ public: enum Flags { NoFlags = 0x0, UseNearestFilter = 0x1, NeedsYFlip = 0x2, ForceSingleTile = 0x4 }; - enum TextureShareType { - ThreadShared = 0x0, - ProcessShared = 0x1 - }; - typedef gfxASurface::gfxContentType ContentType; virtual ~TextureImage() {} /** * Returns a gfxASurface for updating |aRegion| of the client's * image if successul, NULL if not. |aRegion|'s bounds must fit * within Size(); its coordinate space (if any) is ignored. If @@ -848,53 +842,17 @@ public: virtual bool SupportsFramebufferMultisample() { return IsExtensionSupported(EXT_framebuffer_multisample) || IsExtensionSupported(ANGLE_framebuffer_multisample); } virtual bool SupportsOffscreenSplit() { return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit); } - /** - * Create new shared GLContext content handle, must be released by ReleaseSharedHandle. - */ - virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType) { return nsnull; } - /** - * Publish GLContext content to intermediate buffer attached to shared handle. - * Shared handle content is ready to be used after call returns, and no need extra Flush/Finish are required. - * GLContext must be current before this call - */ - virtual void UpdateSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) { } - /** - * - It is better to call ReleaseSharedHandle before original GLContext destroyed, - * otherwise warning will be thrown on attempt to destroy Texture associated with SharedHandle, depends on backend implementation. - * - It does not require to be called on context where it was created, - * because SharedHandle suppose to keep Context reference internally, - * or don't require specific context at all, for example IPC SharedHandle. - * - Not recommended to call this between AttachSharedHandle and Draw Target call. - * if it is really required for some special backend, then DetachSharedHandle API must be added with related implementation. - * - It is recommended to stop any possible access to SharedHandle (Attachments, pending GL calls) before calling Release, - * otherwise some artifacts might appear or even crash if API backend implementation does not expect that. - * SharedHandle (currently EGLImage) does not require GLContext because it is EGL call, and can be destroyed - * at any time, unless EGLImage have siblings (which are not expected with current API). - */ - virtual void ReleaseSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) { } - /** - * Attach Shared GL Handle to GL_TEXTURE_2D target - * GLContext must be current before this call - */ - virtual bool AttachSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) { return false; } - /** - * Detach Shared GL Handle from GL_TEXTURE_2D target - */ - virtual void DetachSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) { return; } + private: GLuint mUserBoundDrawFBO; GLuint mUserBoundReadFBO; GLuint mInternalBoundDrawFBO; GLuint mInternalBoundReadFBO; public:
--- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -253,17 +253,16 @@ public: , mConfig(aConfig) , mSurface(aSurface), mContext(aContext) , mPlatformContext(nsnull) , mThebesSurface(nsnull) , mBound(false) , mIsPBuffer(false) , mIsDoubleBuffered(false) , mCanBindToTexture(false) - , mShareWithEGLImage(false) { // any EGL contexts will always be GLESv2 SetIsGLES2(true); #ifdef DEBUG printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY()); #endif } @@ -323,20 +322,16 @@ public: return false; } bool ok = InitWithPrefix("gl", true); PR_STATIC_ASSERT(sizeof(GLint) >= sizeof(int32_t)); mMaxTextureImageSize = PR_INT32_MAX; - mShareWithEGLImage = sEGLLibrary.HasKHRImageBase() && - sEGLLibrary.HasKHRImageTexture2D() && - IsExtensionSupported(OES_EGL_image); - if (ok) InitFramebuffers(); return ok; } bool IsDoubleBuffered() { return mIsDoubleBuffered; @@ -584,37 +579,29 @@ public: return h; } virtual bool HasLockSurface() { return sEGLLibrary.HasKHRLockSurface(); } - virtual SharedTextureHandle CreateSharedHandle(TextureImage::TextureShareType aType); - virtual void UpdateSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle); - virtual void ReleaseSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle); - virtual bool AttachSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle); protected: friend class GLContextProviderEGL; EGLConfig mConfig; EGLSurface mSurface; EGLContext mContext; void *mPlatformContext; nsRefPtr<gfxASurface> mThebesSurface; bool mBound; bool mIsPBuffer; bool mIsDoubleBuffered; bool mCanBindToTexture; - bool mShareWithEGLImage; static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config, EGLenum bindToTextureFormat, gfxIntSize& pbsize) { nsTArray<EGLint> pbattrs(16); EGLSurface surface = nsnull; @@ -650,171 +637,16 @@ protected: NS_WARNING("Failed to create pbuffer surface"); return nsnull; } return surface; } }; -class EGLTextureWrapper -{ -public: - EGLTextureWrapper(GLContext* aContext, GLuint aTexture) - : mContext(aContext) - , mTexture(aTexture) - , mEGLImage(nsnull) - { - } - - bool CreateEGLImage() { - MOZ_ASSERT(!mEGLImage && mTexture && sEGLLibrary.HasKHRImageBase()); - static const EGLint eglAttributes[] = { - LOCAL_EGL_NONE - }; - GLContextEGL* ctx = static_cast<GLContextEGL*>(mContext.get()); - mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), ctx->Context(), LOCAL_EGL_GL_TEXTURE_2D, - (EGLClientBuffer)mTexture, eglAttributes); - if (!mEGLImage) { -#ifdef DEBUG - printf_stderr("Could not create EGL images: ERROR (0x%04x)\n", sEGLLibrary.fGetError()); -#endif - return false; - } - return true; - } - - virtual ~EGLTextureWrapper() { - if (mEGLImage) { - sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mEGLImage); - mEGLImage = nsnull; - } - } - - GLuint GetTextureID() { - return mTexture; - } - - GLContext* GetContext() { - return mContext.get(); - } - - const EGLImage GetEGLImage() { - return mEGLImage; - } - -private: - nsRefPtr<GLContext> mContext; - GLuint mTexture; - EGLImage mEGLImage; -}; - -void -GLContextEGL::UpdateSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) -{ - if (aType != TextureImage::ThreadShared) { - NS_ERROR("Implementation not available for this sharing type"); - return; - } - - NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime"); - - EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle; - // We need to copy the current GLContext drawing buffer to the texture - // exported by the EGLImage. Need to save both the read FBO and the texture - // binding, because we're going to munge them to do this. - GLuint prevRead = GetUserBoundReadFBO(); - GLint oldtex = -1; - BindUserReadFBO(0); - fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldtex); - MOZ_ASSERT(oldtex != -1); - fBindTexture(LOCAL_GL_TEXTURE_2D, wrap->GetTextureID()); - - // CopyTexSubImage2D, is ~2x slower than simple FBO render to texture with draw quads, - // but render with draw quads require complex and hard to maintain context save/restore code - fCopyTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0, 0, 0, - 0, 0, mOffscreenActualSize.width, - mOffscreenActualSize.height); - - fBindTexture(LOCAL_GL_TEXTURE_2D, oldtex); - BindUserReadFBO(prevRead); - - // Make Shared Handle fully resolved in order to - // guarantee content ready to draw in different thread GLContext - GuaranteeResolve(); -} - -SharedTextureHandle -GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType) -{ - if (aType != TextureImage::ThreadShared) - return nsnull; - - if (!mShareWithEGLImage) - return nsnull; - - MakeCurrent(); - GLuint texture = 0; - ContextFormat fmt = ActualFormat(); - CreateTextureForOffscreen(ChooseGLFormats(fmt), mOffscreenSize, texture); - // texture ownership moved to EGLTextureWrapper after this point - // and texture will be deleted in EGLTextureWrapper dtor - EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture); - if (!tex->CreateEGLImage()) { - NS_ERROR("EGLImage creation for EGLTextureWrapper failed"); - ReleaseSharedHandle(aType, (SharedTextureHandle)tex); - - // Stop trying to create shared image Handle - mShareWithEGLImage = false; - return nsnull; - } - // Raw pointer shared across threads - return (SharedTextureHandle)tex; -} - -void GLContextEGL::ReleaseSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) -{ - if (aType != TextureImage::ThreadShared) { - NS_ERROR("Implementation not available for this sharing type"); - return; - } - - NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime"); - - EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle; - GLContext *ctx = wrap->GetContext(); - if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) { - ctx = ctx->GetSharedContext(); - } - // If we have a context, then we need to delete the texture; - // if we don't have a context (either real or shared), - // then they went away when the contex was deleted, because it - // was the only one that had access to it. - if (ctx && !ctx->IsDestroyed() && ctx->MakeCurrent()) { - GLuint texture = wrap->GetTextureID(); - ctx->fDeleteTextures(1, &texture); - } - delete wrap; -} - -bool GLContextEGL::AttachSharedHandle(TextureImage::TextureShareType aType, - SharedTextureHandle aSharedHandle) -{ - if (aType != TextureImage::ThreadShared) - return false; - - NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime"); - - EGLTextureWrapper* wrap = (EGLTextureWrapper*)aSharedHandle; - sEGLLibrary.fImageTargetTexture2DOES(LOCAL_GL_TEXTURE_2D, wrap->GetEGLImage()); - return true; -} - bool GLContextEGL::BindTex2DOffscreen(GLContext *aOffscreen) { if (aOffscreen->GetContextType() != ContextTypeEGL) { NS_WARNING("non-EGL context"); return false; }
--- a/gfx/gl/GLDefs.h +++ b/gfx/gl/GLDefs.h @@ -3248,19 +3248,16 @@ typedef void* GLeglImage; #define LOCAL_EGL_READ_SURFACE_BIT_KHR 0x0001 #define LOCAL_EGL_WRITE_SURFACE_BIT_KHR 0x0002 #define LOCAL_EGL_LOCK_SURFACE_BIT_KHR 0x0080 #define LOCAL_EGL_CORE_NATIVE_ENGINE 0x305B #define LOCAL_EGL_READ 0x305A #define LOCAL_EGL_DRAW 0x3059 #define LOCAL_EGL_CONTEXT_LOST 0x300E -// EGL_KHR_gl_texture_2D_image -#define LOCAL_EGL_GL_TEXTURE_2D 0x30B1 - // EGL_KHR_fence_sync #define LOCAL_EGL_SYNC_FENCE 0x30F9 #define LOCAL_EGL_SYNC_TYPE 0x30F7 #define LOCAL_EGL_SYNC_STATUS 0x30F1 #define LOCAL_EGL_SYNC_CONDITION 0x30F8 #define LOCAL_EGL_SIGNALED 0x30F2 #define LOCAL_EGL_UNSIGNALED 0x30F3 #define LOCAL_EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
--- a/gfx/layers/basic/BasicCanvasLayer.cpp +++ b/gfx/layers/basic/BasicCanvasLayer.cpp @@ -4,23 +4,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/layers/PLayersParent.h" #include "gfxImageSurface.h" #include "GLContext.h" #include "gfxUtils.h" #include "BasicLayersImpl.h" -#include "nsXULAppAPI.h" using namespace mozilla::gfx; namespace mozilla { -namespace layers { - +namespace layers { + class BasicCanvasLayer : public CanvasLayer, public BasicImplData { public: BasicCanvasLayer(BasicLayerManager* aLayerManager) : CanvasLayer(aLayerManager, static_cast<BasicImplData*>(this)) { MOZ_COUNT_CTOR(BasicCanvasLayer); @@ -308,38 +307,23 @@ public: virtual void Disconnect() { mBackBuffer = SurfaceDescriptor(); BasicShadowableLayer::Disconnect(); } void DestroyBackBuffer() { - if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor) { - SharedTextureDescriptor handle = mBackBuffer.get_SharedTextureDescriptor(); - if (mGLContext && handle.handle()) { - mGLContext->ReleaseSharedHandle(handle.shareType(), handle.handle()); - mBackBuffer = SurfaceDescriptor(); - } - } else if (IsSurfaceDescriptorValid(mBackBuffer)) { + if (IsSurfaceDescriptorValid(mBackBuffer)) { BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); mBackBuffer = SurfaceDescriptor(); } } private: - typedef mozilla::gl::SharedTextureHandle SharedTextureHandle; - typedef mozilla::gl::TextureImage TextureImage; - SharedTextureHandle GetSharedBackBufferHandle() - { - if (mBackBuffer.type() == SurfaceDescriptor::TSharedTextureDescriptor) - return mBackBuffer.get_SharedTextureDescriptor().handle(); - return nsnull; - } - BasicShadowLayerManager* BasicManager() { return static_cast<BasicShadowLayerManager*>(mManager); } SurfaceDescriptor mBackBuffer; bool mBufferIsOpaque; }; @@ -366,45 +350,16 @@ BasicShadowableCanvasLayer::Initialize(c void BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer) { if (!HasShadow()) { BasicCanvasLayer::Paint(aContext, aMaskLayer); return; } - if (mGLContext && - BasicManager()->GetParentBackendType() == LayerManager::LAYERS_OPENGL) { - TextureImage::TextureShareType flags; - // if process type is default, then it is single-process (non-e10s) - if (XRE_GetProcessType() == GeckoProcessType_Default) - flags = TextureImage::ThreadShared; - else - flags = TextureImage::ProcessShared; - - SharedTextureHandle handle = GetSharedBackBufferHandle(); - if (!handle) { - handle = mGLContext->CreateSharedHandle(flags); - if (handle) { - mBackBuffer = SharedTextureDescriptor(flags, handle, mBounds.Size()); - } - } - if (handle) { - mGLContext->MakeCurrent(); - mGLContext->UpdateSharedHandle(flags, handle); - FireDidTransactionCallback(); - BasicManager()->PaintedCanvas(BasicManager()->Hold(this), - mNeedsYFlip, - mBackBuffer); - // Move SharedTextureHandle ownership to ShadowLayer - mBackBuffer = SurfaceDescriptor(); - return; - } - } - bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE); if (!IsSurfaceDescriptorValid(mBackBuffer) || isOpaque != mBufferIsOpaque) { DestroyBackBuffer(); mBufferIsOpaque = isOpaque; if (!BasicManager()->AllocBuffer( gfxIntSize(mBounds.width, mBounds.height), isOpaque ? @@ -420,17 +375,18 @@ BasicShadowableCanvasLayer::Paint(gfxCon if (aMaskLayer) { static_cast<BasicImplData*>(aMaskLayer->ImplData()) ->Paint(aContext, nsnull); } UpdateSurface(backSurface, nsnull); FireDidTransactionCallback(); BasicManager()->PaintedCanvas(BasicManager()->Hold(this), - mNeedsYFlip, mBackBuffer); + mNeedsYFlip ? true : false, + mBackBuffer); } class BasicShadowCanvasLayer : public ShadowCanvasLayer, public BasicImplData { public: BasicShadowCanvasLayer(BasicShadowLayerManager* aLayerManager) : ShadowCanvasLayer(aLayerManager, static_cast<BasicImplData*>(this))
--- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -18,18 +18,16 @@ using nsIntPoint; using nsIntRect; using nsIntRegion; using nsIntSize; using mozilla::GraphicsFilterType; using mozilla::layers::FrameMetrics; using mozilla::layers::SurfaceDescriptorX11; using mozilla::null_t; using mozilla::WindowsHandle; -using mozilla::gl::SharedTextureHandle; -using mozilla::gl::TextureImage::TextureShareType; /** * The layers protocol is spoken between thread contexts that manage * layer (sub)trees. The protocol comprises atomically publishing * layer subtrees to a "shadow" thread context (which grafts the * subtree into its own tree), and atomically updating a published * subtree. ("Atomic" in this sense is wrt painting.) */ @@ -43,27 +41,20 @@ struct OpCreateContainerLayer { PLayer struct OpCreateImageLayer { PLayer layer; }; struct OpCreateColorLayer { PLayer layer; }; struct OpCreateCanvasLayer { PLayer layer; }; struct SurfaceDescriptorD3D10 { WindowsHandle handle; }; -struct SharedTextureDescriptor { - TextureShareType shareType; - SharedTextureHandle handle; - nsIntSize size; -}; - union SurfaceDescriptor { Shmem; SurfaceDescriptorD3D10; SurfaceDescriptorX11; - SharedTextureDescriptor; }; struct YUVImage { Shmem Ydata; Shmem Udata; Shmem Vdata; nsIntRect picture; };
--- a/gfx/layers/ipc/ShadowLayerUtils.h +++ b/gfx/layers/ipc/ShadowLayerUtils.h @@ -5,17 +5,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef IPC_ShadowLayerUtils_h #define IPC_ShadowLayerUtils_h #include "IPC/IPCMessageUtils.h" #include "Layers.h" -#include "GLContext.h" #if defined(MOZ_ENABLE_D3D10_LAYER) # include "mozilla/layers/ShadowLayerUtilsD3D10.h" #endif #if defined(MOZ_X11) # include "mozilla/layers/ShadowLayerUtilsX11.h" #else @@ -60,34 +59,11 @@ struct ParamTraits<mozilla::layers::Fram template <> struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> { typedef mozilla::layers::SurfaceDescriptorX11 paramType; static void Write(Message*, const paramType&) {} static bool Read(const Message*, void**, paramType*) { return false; } }; #endif // !defined(MOZ_HAVE_XSURFACEDESCRIPTOR) -template<> -struct ParamTraits<mozilla::gl::TextureImage::TextureShareType> -{ - typedef mozilla::gl::TextureImage::TextureShareType paramType; - - static void Write(Message* msg, const paramType& param) - { - MOZ_STATIC_ASSERT(sizeof(paramType) <= sizeof(int32), - "TextureShareType assumes to be int32"); - WriteParam(msg, int32(param)); - } - - static bool Read(const Message* msg, void** iter, paramType* result) - { - int32 type; - if (!ReadParam(msg, iter, &type)) - return false; - - *result = paramType(type); - return true; - } -}; - } #endif // IPC_ShadowLayerUtils_h
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp +++ b/gfx/layers/opengl/CanvasLayerOGL.cpp @@ -27,33 +27,16 @@ #ifdef MOZ_X11 #include "gfxXlibSurface.h" #endif using namespace mozilla; using namespace mozilla::layers; using namespace mozilla::gl; -static void -MakeTextureIfNeeded(GLContext* gl, GLuint& aTexture) -{ - if (aTexture != 0) - return; - - gl->fGenTextures(1, &aTexture); - - gl->fActiveTexture(LOCAL_GL_TEXTURE0); - gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture); - - gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR); - gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR); - gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); - gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); -} - void CanvasLayerOGL::Destroy() { if (!mDestroyed) { CleanupResources(); mDestroyed = true; } } @@ -83,17 +66,17 @@ CanvasLayerOGL::Initialize(const Data& a gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(aData.mSurface); mPixmap = xsurf->GetGLXPixmap(); if (mPixmap) { if (aData.mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) { mLayerProgram = gl::RGBALayerProgramType; } else { mLayerProgram = gl::RGBXLayerProgramType; } - MakeTextureIfNeeded(gl(), mTexture); + MakeTexture(); } } #endif } else if (aData.mGLContext) { if (!aData.mGLContext->IsOffscreen()) { NS_WARNING("CanvasLayerOGL with a non-offscreen GL context given"); return; } @@ -109,24 +92,41 @@ CanvasLayerOGL::Initialize(const Data& a mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); // Check the maximum texture size supported by GL. glTexImage2D supports // images of up to 2 + GL_MAX_TEXTURE_SIZE GLint texSize = gl()->GetMaxTextureSize(); if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) { mDelayedUpdates = true; - MakeTextureIfNeeded(gl(), mTexture); + MakeTexture(); // This should only ever occur with 2d canvas, WebGL can't already have a texture // of this size can it? NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "Invalid texture size when WebGL surface already exists at that size?"); } } +void +CanvasLayerOGL::MakeTexture() +{ + if (mTexture != 0) + return; + + gl()->fGenTextures(1, &mTexture); + + gl()->fActiveTexture(LOCAL_GL_TEXTURE0); + gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); + + gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR); + gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR); + gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); + gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); +} + /** * Following UpdateSurface(), mTexture on context this->gl() should contain the data we want, * unless mDelayedUpdates is true because of a too-large surface. */ void CanvasLayerOGL::UpdateSurface() { if (!mDirty) @@ -151,17 +151,17 @@ CanvasLayerOGL::UpdateSurface() // Can texture share, just make sure it's resolved first mCanvasGLContext->MakeCurrent(); mCanvasGLContext->GuaranteeResolve(); if (gl()->BindOffscreenNeedsTexture(mCanvasGLContext) && mTexture == 0) { mOGLManager->MakeCurrent(); - MakeTextureIfNeeded(gl(), mTexture); + MakeTexture(); } } else { nsRefPtr<gfxASurface> updatedAreaSurface; if (mDrawTarget) { // TODO: This is suboptimal - We should have direct handling for the surface types instead of // going via a gfxASurface. updatedAreaSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget); @@ -279,27 +279,21 @@ void CanvasLayerOGL::CleanupResources() { if (mTexture) { gl()->MakeCurrent(); gl()->fDeleteTextures(1, &mTexture); } } -static bool -IsValidSharedTexDescriptor(const SurfaceDescriptor& aDescriptor) -{ - return aDescriptor.type() == SurfaceDescriptor::TSharedTextureDescriptor; -} ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager) : ShadowCanvasLayer(aManager, nsnull) , LayerOGL(aManager) , mNeedsYFlip(false) - , mTexture(0) { mImplData = static_cast<LayerOGL*>(this); } ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL() {} void @@ -321,155 +315,115 @@ ShadowCanvasLayerOGL::Init(const CanvasS mNeedsYFlip ? TextureImage::NeedsYFlip : TextureImage::NoFlags); } void ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront, bool needYFlip, CanvasSurface* aNewBack) { - if (mDestroyed) { - *aNewBack = aNewFront; - return; - } - - if (IsValidSharedTexDescriptor(aNewFront)) { - MakeTextureIfNeeded(gl(), mTexture); - if (!IsValidSharedTexDescriptor(mFrontBufferDescriptor)) { - mFrontBufferDescriptor = SharedTextureDescriptor(TextureImage::ThreadShared, 0, nsIntSize(0, 0)); - } - *aNewBack = mFrontBufferDescriptor; - mFrontBufferDescriptor = aNewFront; - mNeedsYFlip = needYFlip; - } else { + if (!mDestroyed) { nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront); gfxIntSize sz = surf->GetSize(); if (!mTexImage || mTexImage->GetSize() != sz || mTexImage->GetContentType() != surf->GetContentType()) { Init(aNewFront, needYFlip); } nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height)); mTexImage->DirectUpdate(surf, updateRegion); - *aNewBack = aNewFront; } + + *aNewBack = aNewFront; } void ShadowCanvasLayerOGL::DestroyFrontBuffer() { mTexImage = nsnull; - if (mTexture) { - gl()->MakeCurrent(); - gl()->fDeleteTextures(1, &mTexture); - } - if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) { - SharedTextureDescriptor texDescriptor = mFrontBufferDescriptor.get_SharedTextureDescriptor(); - gl()->ReleaseSharedHandle(texDescriptor.shareType(), texDescriptor.handle()); - mFrontBufferDescriptor = SurfaceDescriptor(); - } } void ShadowCanvasLayerOGL::Disconnect() { Destroy(); } void ShadowCanvasLayerOGL::Destroy() { if (!mDestroyed) { mDestroyed = true; - DestroyFrontBuffer(); + mTexImage = nsnull; } } Layer* ShadowCanvasLayerOGL::GetLayer() { return this; } void ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset) { mOGLManager->MakeCurrent(); + ShaderProgramOGL *program = + mOGLManager->GetProgram(mTexImage->GetShaderProgramType(), + GetMaskLayer()); + + gfx3DMatrix effectiveTransform = GetEffectiveTransform(); - gfxPattern::GraphicsFilter filter = mFilter; #ifdef ANDROID // Bug 691354 // Using the LINEAR filter we get unexplained artifacts. // Use NEAREST when no scaling is required. gfxMatrix matrix; bool is2D = GetEffectiveTransform().Is2D(&matrix); if (is2D && !matrix.HasNonTranslationOrFlip()) { - filter = gfxPattern::FILTER_NEAREST; + mTexImage->SetFilter(gfxPattern::FILTER_NEAREST); + } else { + mTexImage->SetFilter(mFilter); } +#else + mTexImage->SetFilter(mFilter); #endif - ShaderProgramOGL *program; - if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) { - program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(), - true, - GetMaskLayer() ? Mask2d : MaskNone); - } else { - program = mOGLManager->GetProgram(mTexImage->GetShaderProgramType(), - GetMaskLayer()); - } program->Activate(); program->SetLayerTransform(effectiveTransform); program->SetLayerOpacity(GetEffectiveOpacity()); program->SetRenderOffset(aOffset); program->SetTextureUnit(0); program->LoadMask(GetMaskLayer()); - if (IsValidSharedTexDescriptor(mFrontBufferDescriptor)) { - // Shared texture handle rendering path, single texture rendering - SharedTextureDescriptor texDescriptor = mFrontBufferDescriptor.get_SharedTextureDescriptor(); - gl()->fActiveTexture(LOCAL_GL_TEXTURE0); - gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); - if (!gl()->AttachSharedHandle(texDescriptor.shareType(), texDescriptor.handle())) { - NS_ERROR("Failed to attach shared texture handle"); - return; - } - gl()->ApplyFilterToBoundTexture(filter); - program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), texDescriptor.size())); - mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); - gl()->DetachSharedHandle(texDescriptor.shareType(), texDescriptor.handle()); - gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, 0); + mTexImage->BeginTileIteration(); + if (gl()->CanUploadNonPowerOfTwo()) { + do { + TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); + program->SetLayerQuadRect(mTexImage->GetTileRect()); + mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles? + } while (mTexImage->NextTile()); } else { - // Tiled texture image rendering path - mTexImage->SetFilter(filter); - mTexImage->BeginTileIteration(); - if (gl()->CanUploadNonPowerOfTwo()) { - do { - TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); - program->SetLayerQuadRect(mTexImage->GetTileRect()); - mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles? - } while (mTexImage->NextTile()); - } else { - do { - TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); - program->SetLayerQuadRect(mTexImage->GetTileRect()); - // We can't use BindAndDrawQuad because that always uploads the whole texture from 0.0f -> 1.0f - // in x and y. We use BindAndDrawQuadWithTextureRect to actually draw a subrect of the texture - // We need to reset the origin to 0,0 from the tile rect because the tile originates at 0,0 in the - // actual texture, even though its origin in the composed (tiled) texture is not 0,0 - // FIXME: we need to handle mNeedsYFlip, Bug #728625 - mOGLManager->BindAndDrawQuadWithTextureRect(program, - nsIntRect(0, 0, mTexImage->GetTileRect().width, - mTexImage->GetTileRect().height), - mTexImage->GetTileRect().Size(), - mTexImage->GetWrapMode(), - mNeedsYFlip); - } while (mTexImage->NextTile()); - } + do { + TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0); + program->SetLayerQuadRect(mTexImage->GetTileRect()); + // We can't use BindAndDrawQuad because that always uploads the whole texture from 0.0f -> 1.0f + // in x and y. We use BindAndDrawQuadWithTextureRect to actually draw a subrect of the texture + // We need to reset the origin to 0,0 from the tile rect because the tile originates at 0,0 in the + // actual texture, even though its origin in the composed (tiled) texture is not 0,0 + // FIXME: we need to handle mNeedsYFlip, Bug #728625 + mOGLManager->BindAndDrawQuadWithTextureRect(program, + nsIntRect(0, 0, mTexImage->GetTileRect().width, + mTexImage->GetTileRect().height), + mTexImage->GetTileRect().Size(), + mTexImage->GetWrapMode(), + mNeedsYFlip); + } while (mTexImage->NextTile()); } } void ShadowCanvasLayerOGL::CleanupResources() { DestroyFrontBuffer(); }
--- a/gfx/layers/opengl/CanvasLayerOGL.h +++ b/gfx/layers/opengl/CanvasLayerOGL.h @@ -48,16 +48,17 @@ public: protected: void UpdateSurface(); nsRefPtr<gfxASurface> mCanvasSurface; nsRefPtr<GLContext> mCanvasGLContext; gl::ShaderProgramType mLayerProgram; RefPtr<gfx::DrawTarget> mDrawTarget; + void MakeTexture(); GLuint mTexture; bool mDelayedUpdates; bool mGLBufferIsPremultiplied; bool mNeedsYFlip; #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO) GLXPixmap mPixmap; #endif @@ -121,15 +122,13 @@ public: virtual void RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset); virtual void CleanupResources(); private: nsRefPtr<TextureImage> mTexImage; bool mNeedsYFlip; - SurfaceDescriptor mFrontBufferDescriptor; - GLuint mTexture; }; } /* layers */ } /* mozilla */ #endif /* GFX_IMAGELAYEROGL_H */