author | Jamie Nicol <jnicol@mozilla.com> |
Thu, 20 Oct 2016 17:11:00 +0100 | |
changeset 319282 | b0b2881014728cae83a25992df40c0db38437b90 |
parent 319281 | e35c6a772ec4c3549fc596b48457dbd6f68b6a8b |
child 319283 | 4a4b3074ade68a04ea020a319229dcf59422df30 |
push id | 30869 |
push user | philringnalda@gmail.com |
push date | Wed, 26 Oct 2016 04:57:48 +0000 |
treeherder | mozilla-central@9471b3c49b2c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nical |
bugs | 1311642 |
milestone | 52.0a1 |
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
|
gfx/gl/GLContextProviderCGL.mm | file | annotate | diff | comparison | revisions | |
gfx/gl/GLTextureImage.cpp | file | annotate | diff | comparison | revisions | |
gfx/gl/GLTextureImage.h | file | annotate | diff | comparison | revisions | |
gfx/gl/TextureImageCGL.h | file | annotate | diff | comparison | revisions | |
gfx/gl/TextureImageCGL.mm | file | annotate | diff | comparison | revisions | |
gfx/gl/TextureImageEGL.cpp | file | annotate | diff | comparison | revisions | |
gfx/gl/TextureImageEGL.h | file | annotate | diff | comparison | revisions | |
gfx/gl/moz.build | file | annotate | diff | comparison | revisions | |
gfx/layers/opengl/GLBlitTextureImageHelper.cpp | file | annotate | diff | comparison | revisions | |
gfx/layers/opengl/TextureHostOGL.cpp | file | annotate | diff | comparison | revisions |
--- a/gfx/gl/GLContextProviderCGL.mm +++ b/gfx/gl/GLContextProviderCGL.mm @@ -1,16 +1,15 @@ /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- * This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ #include "GLContextProvider.h" #include "GLContextCGL.h" -#include "TextureImageCGL.h" #include "nsDebug.h" #include "nsIWidget.h" #include <OpenGL/gl.h> #include "gfxFailure.h" #include "gfxPrefs.h" #include "prenv.h" #include "GeckoProfiler.h" #include "mozilla/gfx/MacIOSurface.h"
--- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -10,38 +10,31 @@ #include "gfxUtils.h" #include "gfx2DGlue.h" #include "mozilla/gfx/2D.h" #include "ScopedGLHelpers.h" #include "GLUploadHelpers.h" #include "GfxTexturesReporter.h" #include "TextureImageEGL.h" -#ifdef XP_MACOSX -#include "TextureImageCGL.h" -#endif using namespace mozilla::gfx; namespace mozilla { namespace gl { already_AddRefed<TextureImage> CreateTextureImage(GLContext* gl, const gfx::IntSize& aSize, TextureImage::ContentType aContentType, GLenum aWrapMode, TextureImage::Flags aFlags, TextureImage::ImageFormat aImageFormat) { switch (gl->GetContextType()) { -#ifdef XP_MACOSX - case GLContextType::CGL: - return CreateTextureImageCGL(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat); -#endif case GLContextType::EGL: return CreateTextureImageEGL(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat); default: { GLint maxTextureSize; gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTextureSize); if (aSize.width > maxTextureSize || aSize.height > maxTextureSize) { NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!"); return CreateTiledTextureImage(gl, aSize, aContentType, aFlags, aImageFormat); @@ -56,20 +49,16 @@ CreateTextureImage(GLContext* gl, static already_AddRefed<TextureImage> TileGenFunc(GLContext* gl, const IntSize& aSize, TextureImage::ContentType aContentType, TextureImage::Flags aFlags, TextureImage::ImageFormat aImageFormat) { switch (gl->GetContextType()) { -#ifdef XP_MACOSX - case GLContextType::CGL: - return TileGenFuncCGL(gl, aSize, aContentType, aFlags); -#endif case GLContextType::EGL: return TileGenFuncEGL(gl, aSize, aContentType, aFlags, aImageFormat); default: return CreateBasicTextureImage(gl, aSize, aContentType, LOCAL_GL_CLAMP_TO_EDGE, aFlags); } } @@ -126,112 +115,24 @@ BasicTextureImage::~BasicTextureImage() // 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->MakeCurrent()) { ctx->fDeleteTextures(1, &mTexture); } } -gfx::DrawTarget* -BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) -{ - NS_ASSERTION(!mUpdateDrawTarget, "BeginUpdate() without EndUpdate()?"); - - // determine the region the client will need to repaint - if (CanUploadSubTextures(mGLContext)) { - GetUpdateRegion(aRegion); - } else { - aRegion = IntRect(IntPoint(0, 0), mSize); - } - - mUpdateRegion = aRegion; - - IntRect rgnSize = mUpdateRegion.GetBounds(); - if (!IntRect(IntPoint(0, 0), mSize).Contains(rgnSize)) { - NS_ERROR("update outside of image"); - return nullptr; - } - - gfx::SurfaceFormat format = - (GetContentType() == gfxContentType::COLOR) ? - gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::B8G8R8A8; - mUpdateDrawTarget = - GetDrawTargetForUpdate(gfx::IntSize(rgnSize.width, rgnSize.height), format); - - return mUpdateDrawTarget; -} - -void -BasicTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) -{ - // if the texture hasn't been initialized yet, or something important - // changed, we need to recreate our backing surface and force the - // client to paint everything - if (mTextureState != Valid) { - aForRegion = IntRect(IntPoint(0, 0), mSize); - } -} - -void -BasicTextureImage::EndUpdate() -{ - NS_ASSERTION(!!mUpdateDrawTarget, "EndUpdate() without BeginUpdate()?"); - - // FIXME: this is the slow boat. Make me fast (with GLXPixmap?). - - RefPtr<gfx::SourceSurface> updateSnapshot = mUpdateDrawTarget->Snapshot(); - RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface(); - - bool relative = FinishedSurfaceUpdate(); - bool needInit = mTextureState == Created; - size_t uploadSize; - mTextureFormat = - UploadSurfaceToTexture(mGLContext, - updateData, - mUpdateRegion, - mTexture, - &uploadSize, - needInit, - mUpdateOffset, - relative); - FinishedSurfaceUpload(); - if (uploadSize > 0) { - UpdateUploadSize(uploadSize); - } - - mUpdateDrawTarget = nullptr; - mTextureState = Valid; -} - void BasicTextureImage::BindTexture(GLenum aTextureUnit) { mGLContext->fActiveTexture(aTextureUnit); mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0); } -already_AddRefed<gfx::DrawTarget> -BasicTextureImage::GetDrawTargetForUpdate(const gfx::IntSize& aSize, gfx::SurfaceFormat aFmt) -{ - return gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO, aSize, aFmt); -} - -bool -BasicTextureImage::FinishedSurfaceUpdate() -{ - return false; -} - -void -BasicTextureImage::FinishedSurfaceUpload() -{ -} - bool BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0, 0) */) { IntRect bounds = aRegion.GetBounds(); nsIntRegion region; if (mTextureState != Valid) { bounds = IntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); @@ -255,18 +156,16 @@ BasicTextureImage::DirectUpdate(gfx::Dat } mTextureState = Valid; return true; } void BasicTextureImage::Resize(const gfx::IntSize& aSize) { - NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?"); - mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); // This matches the logic in UploadImageDataToTexture so that // we avoid mixing formats. GLenum format; GLenum type; if (mGLContext->GetPreferredARGB32Format() == LOCAL_GL_BGRA) { MOZ_ASSERT(!mGLContext->IsGLES()); @@ -312,17 +211,16 @@ BasicTextureImage::BasicTextureImage(GLu GLenum aWrapMode, ContentType aContentType, GLContext* aContext, TextureImage::Flags aFlags) : TextureImage(aSize, aWrapMode, aContentType, aFlags) , mTexture(aTexture) , mTextureState(Created) , mGLContext(aContext) - , mUpdateOffset(0, 0) {} static bool WantsSmallTiles(GLContext* gl) { // We can't use small tiles on the SGX 540, because of races in texture upload. if (gl->WorkAroundDriverBugs() && gl->Renderer() == GLRenderer::SGX540) @@ -342,17 +240,16 @@ TiledTextureImage::TiledTextureImage(GLC gfx::IntSize aSize, TextureImage::ContentType aContentType, TextureImage::Flags aFlags, TextureImage::ImageFormat aImageFormat) : TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aFlags) , mCurrentImage(0) , mIterationCallback(nullptr) , mIterationCallbackData(nullptr) - , mInUpdate(false) , mRows(0) , mColumns(0) , mGL(aGL) , mTextureState(Created) , mImageFormat(aImageFormat) { if (!(aFlags & TextureImage::DisallowBigImage) && WantsSmallTiles(mGL)) { mTileSize = 256; @@ -421,163 +318,16 @@ TiledTextureImage::DirectUpdate(gfx::Dat } while (NextTile() || (mTextureState != Valid)); mCurrentImage = oldCurrentImage; mTextureFormat = mImages[0]->GetTextureFormat(); mTextureState = Valid; return result; } -void -TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion) -{ - if (mTextureState != Valid) { - // if the texture hasn't been initialized yet, or something important - // changed, we need to recreate our backing surface and force the - // client to paint everything - aForRegion = IntRect(IntPoint(0, 0), mSize); - return; - } - - nsIntRegion newRegion; - - // We need to query each texture with the region it will be drawing and - // set aForRegion to be the combination of all of these regions - for (unsigned i = 0; i < mImages.Length(); i++) { - int xPos = (i % mColumns) * mTileSize; - int yPos = (i / mColumns) * mTileSize; - IntRect imageRect = IntRect(IntPoint(xPos,yPos), - mImages[i]->GetSize()); - - if (aForRegion.Intersects(imageRect)) { - // Make a copy of the region - nsIntRegion subRegion; - subRegion.And(aForRegion, imageRect); - // Translate it into tile-space - subRegion.MoveBy(-xPos, -yPos); - // Query region - mImages[i]->GetUpdateRegion(subRegion); - // Translate back - subRegion.MoveBy(xPos, yPos); - // Add to the accumulated region - newRegion.Or(newRegion, subRegion); - } - } - - aForRegion = newRegion; -} - -gfx::DrawTarget* -TiledTextureImage::BeginUpdate(nsIntRegion& aRegion) -{ - NS_ASSERTION(!mInUpdate, "nested update"); - mInUpdate = true; - - // Note, we don't call GetUpdateRegion here as if the updated region is - // fully contained in a single tile, we get to avoid iterating through - // the tiles again (and a little copying). - if (mTextureState != Valid) - { - // if the texture hasn't been initialized yet, or something important - // changed, we need to recreate our backing surface and force the - // client to paint everything - aRegion = IntRect(IntPoint(0, 0), mSize); - } - - IntRect bounds = aRegion.GetBounds(); - - for (unsigned i = 0; i < mImages.Length(); i++) { - int xPos = (i % mColumns) * mTileSize; - int yPos = (i / mColumns) * mTileSize; - nsIntRegion imageRegion = - nsIntRegion(IntRect(IntPoint(xPos,yPos), - mImages[i]->GetSize())); - - // a single Image can handle this update request - if (imageRegion.Contains(aRegion)) { - // adjust for tile offset - aRegion.MoveBy(-xPos, -yPos); - // forward the actual call - RefPtr<gfx::DrawTarget> drawTarget = mImages[i]->BeginUpdate(aRegion); - // caller expects container space - aRegion.MoveBy(xPos, yPos); - // we don't have a temp surface - mUpdateDrawTarget = nullptr; - // remember which image to EndUpdate - mCurrentImage = i; - return drawTarget.get(); - } - } - - // Get the real updated region, taking into account the capabilities of - // each TextureImage tile - GetUpdateRegion(aRegion); - mUpdateRegion = aRegion; - bounds = aRegion.GetBounds(); - - // update covers multiple Images - create a temp surface to paint in - gfx::SurfaceFormat format = - (GetContentType() == gfxContentType::COLOR) ? - gfx::SurfaceFormat::B8G8R8X8: gfx::SurfaceFormat::B8G8R8A8; - mUpdateDrawTarget = gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO, - bounds.Size(), - format); - - return mUpdateDrawTarget;; -} - -void -TiledTextureImage::EndUpdate() -{ - NS_ASSERTION(mInUpdate, "EndUpdate not in update"); - if (!mUpdateDrawTarget) { // update was to a single TextureImage - mImages[mCurrentImage]->EndUpdate(); - mInUpdate = false; - mTextureState = Valid; - mTextureFormat = mImages[mCurrentImage]->GetTextureFormat(); - return; - } - - RefPtr<gfx::SourceSurface> updateSnapshot = mUpdateDrawTarget->Snapshot(); - RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface(); - - // upload tiles from temp surface - for (unsigned i = 0; i < mImages.Length(); i++) { - int xPos = (i % mColumns) * mTileSize; - int yPos = (i / mColumns) * mTileSize; - IntRect imageRect = IntRect(IntPoint(xPos,yPos), mImages[i]->GetSize()); - - nsIntRegion subregion; - subregion.And(mUpdateRegion, imageRect); - if (subregion.IsEmpty()) - continue; - subregion.MoveBy(-xPos, -yPos); // Tile-local space - // copy tile from temp target - gfx::DrawTarget* drawTarget = mImages[i]->BeginUpdate(subregion); - MOZ_ASSERT(drawTarget->GetBackendType() == BackendType::CAIRO, - "updateSnapshot should not have been converted to data"); - gfxUtils::ClipToRegion(drawTarget, subregion); - Size size(updateData->GetSize().width, - updateData->GetSize().height); - drawTarget->DrawSurface(updateData, - Rect(Point(-xPos, -yPos), size), - Rect(Point(0, 0), size), - DrawSurfaceOptions(), - DrawOptions(1.0, CompositionOp::OP_SOURCE, - AntialiasMode::NONE)); - drawTarget->PopClip(); - mImages[i]->EndUpdate(); - } - - mUpdateDrawTarget = nullptr; - mInUpdate = false; - mTextureFormat = mImages[0]->GetTextureFormat(); - mTextureState = Valid; -} - void TiledTextureImage::BeginBigImageIteration() { mCurrentImage = 0; } bool TiledTextureImage::NextTile() { bool continueIteration = true;
--- a/gfx/gl/GLTextureImage.h +++ b/gfx/gl/GLTextureImage.h @@ -22,30 +22,19 @@ class DrawTarget; } // namespace gfx } // namespace mozilla namespace mozilla { namespace gl { class GLContext; /** - * A TextureImage encapsulates a surface that can be drawn to by a - * Thebes gfxContext and (hopefully efficiently!) synchronized to a - * texture in the server. TextureImages are associated with one and - * only one GLContext. - * - * Implementation note: TextureImages attempt to unify two categories - * of backends - * - * (1) proxy to server-side object that can be bound to a texture; - * e.g. Pixmap on X11. - * - * (2) efficient manager of texture memory; e.g. by having clients draw - * into a scratch buffer which is then uploaded with - * glTexSubImage2D(). + * A TextureImage provides a mechanism to synchronize data from a + * surface to a texture in the server. TextureImages are associated + * with one and only one GLContext. */ class TextureImage { NS_INLINE_DECL_REFCOUNTING(TextureImage) public: enum TextureState { Created, // Texture created, but has not had glTexImage called to initialize it. @@ -66,56 +55,16 @@ public: static already_AddRefed<TextureImage> Create( GLContext* gl, const gfx::IntSize& aSize, TextureImage::ContentType aContentType, GLenum aWrapMode, TextureImage::Flags aFlags = TextureImage::NoFlags); /** - * Returns a gfxASurface for updating |aRegion| of the client's - * image if successul, nullptr if not. |aRegion|'s bounds must fit - * within Size(); its coordinate space (if any) is ignored. If - * the update begins successfully, the returned gfxASurface is - * owned by this. Otherwise, nullptr is returned. - * - * |aRegion| is an inout param: the returned region is what the - * client must repaint. Category (1) regions above can - * efficiently handle repaints to "scattered" regions, while (2) - * can only efficiently handle repaints to rects. - * - * Painting the returned surface outside of |aRegion| results - * in undefined behavior. - * - * BeginUpdate() calls cannot be "nested", and each successful - * BeginUpdate() must be followed by exactly one EndUpdate() (see - * below). Failure to do so can leave this in a possibly - * inconsistent state. Unsuccessful BeginUpdate()s must not be - * followed by EndUpdate(). - */ - virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion) = 0; - /** - * Retrieves the region that will require updating, given a - * region that needs to be updated. This can be used for - * making decisions about updating before calling BeginUpdate(). - * - * |aRegion| is an inout param. - */ - virtual void GetUpdateRegion(nsIntRegion& aForRegion) { - } - /** - * Finish the active update and synchronize with the server, if - * necessary. - * - * BeginUpdate() must have been called exactly once before - * EndUpdate(). - */ - virtual void EndUpdate() = 0; - - /** * The Image may contain several textures for different regions (tiles). * These functions iterate over each sub texture image tile. */ virtual void BeginBigImageIteration() { } virtual bool NextTile() { return false; @@ -138,28 +87,20 @@ public: virtual GLuint GetTextureID() = 0; virtual uint32_t GetTileCount() { return 1; } /** * Set this TextureImage's size, and ensure a texture has been - * allocated. Must not be called between BeginUpdate and EndUpdate. + * allocated. * After a resize, the contents are undefined. - * - * If this isn't implemented by a subclass, it will just perform - * a dummy BeginUpdate/EndUpdate pair. */ - virtual void Resize(const gfx::IntSize& aSize) { - mSize = aSize; - nsIntRegion r(gfx::IntRect(0, 0, aSize.width, aSize.height)); - BeginUpdate(r); - EndUpdate(); - } + virtual void Resize(const gfx::IntSize& aSize) = 0; /** * Mark this texture as having valid contents. Call this after modifying * the texture contents externally. */ virtual void MarkValid() {} /** @@ -170,18 +111,18 @@ public: virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)) = 0; bool UpdateFromDataSource(gfx::DataSourceSurface* aSurf, const nsIntRegion* aDstRegion = nullptr, const gfx::IntPoint* aSrcOffset = nullptr); virtual void BindTexture(GLenum aTextureUnit) = 0; /** - * Returns the image format of the texture. Only valid after a matching - * BeginUpdate/EndUpdate pair have been called. + * Returns the image format of the texture. Only valid after + * DirectUpdate has been called. */ virtual gfx::SurfaceFormat GetTextureFormat() { return mTextureFormat; } /** Can be called safely at any time. */ /** @@ -189,17 +130,16 @@ public: * return it. Otherwise return nullptr. */ virtual already_AddRefed<gfxASurface> GetBackingSurface() { return nullptr; } gfx::IntSize GetSize() const; ContentType GetContentType() const { return mContentType; } - virtual bool InUpdate() const = 0; GLenum GetWrapMode() const { return mWrapMode; } void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter) { mSamplingFilter = aSamplingFilter; } protected: friend class GLContext; @@ -251,47 +191,27 @@ public: const gfx::IntSize& aSize, GLenum aWrapMode, ContentType aContentType, GLContext* aContext, TextureImage::Flags aFlags = TextureImage::NoFlags); virtual void BindTexture(GLenum aTextureUnit); - virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion); - virtual void GetUpdateRegion(nsIntRegion& aForRegion); - virtual void EndUpdate(); virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)); virtual GLuint GetTextureID() { return mTexture; } - virtual already_AddRefed<gfx::DrawTarget> - GetDrawTargetForUpdate(const gfx::IntSize& aSize, gfx::SurfaceFormat aFmt); virtual void MarkValid() { mTextureState = Valid; } - // Call when drawing into the update surface is complete. - // Returns true if textures should be upload with a relative - // offset - See UploadSurfaceToTexture. - virtual bool FinishedSurfaceUpdate(); - - // Call after surface data has been uploaded to a texture. - virtual void FinishedSurfaceUpload(); - - virtual bool InUpdate() const { return !!mUpdateDrawTarget; } - virtual void Resize(const gfx::IntSize& aSize); protected: GLuint mTexture; TextureState mTextureState; RefPtr<GLContext> mGLContext; - RefPtr<gfx::DrawTarget> mUpdateDrawTarget; - nsIntRegion mUpdateRegion; - - // The offset into the update surface at which the update rect is located. - nsIntPoint mUpdateOffset; }; /** * A container class that complements many sub TextureImages into a big TextureImage. * Aims to behave just like the real thing. */ class TiledTextureImage final @@ -300,48 +220,39 @@ class TiledTextureImage final public: TiledTextureImage(GLContext* aGL, gfx::IntSize aSize, TextureImage::ContentType, TextureImage::Flags aFlags = TextureImage::NoFlags, TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN); ~TiledTextureImage(); void DumpDiv(); - virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion); - virtual void GetUpdateRegion(nsIntRegion& aForRegion); - virtual void EndUpdate(); virtual void Resize(const gfx::IntSize& aSize); virtual uint32_t GetTileCount(); virtual void BeginBigImageIteration(); virtual bool NextTile(); virtual void SetIterationCallback(BigImageIterationCallback aCallback, void* aCallbackData); virtual gfx::IntRect GetTileRect(); virtual GLuint GetTextureID() { return mImages[mCurrentImage]->GetTextureID(); } virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)); - virtual bool InUpdate() const { return mInUpdate; } virtual void BindTexture(GLenum); protected: virtual gfx::IntRect GetSrcTileRect(); unsigned int mCurrentImage; BigImageIterationCallback mIterationCallback; void* mIterationCallbackData; nsTArray< RefPtr<TextureImage> > mImages; - bool mInUpdate; unsigned int mTileSize; unsigned int mRows, mColumns; GLContext* mGL; - // A temporary draw target to faciliate cross-tile updates. - RefPtr<gfx::DrawTarget> mUpdateDrawTarget; - // The region of update requested - nsIntRegion mUpdateRegion; TextureState mTextureState; TextureImage::ImageFormat mImageFormat; }; /** * Creates a TextureImage of the basic implementation, can be useful in cases * where we know we don't want to use platform-specific TextureImage. * In doubt, use GLContext::CreateTextureImage instead.
deleted file mode 100644 --- a/gfx/gl/TextureImageCGL.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 TextureImageCGL_h_ -#define TextureImageCGL_h_ - -#include "GLTextureImage.h" -#include "GLContextTypes.h" -#include "nsSize.h" - -namespace mozilla { -namespace gl { - -class TextureImageCGL : public BasicTextureImage -{ -public: - - TextureImageCGL(GLuint aTexture, - const gfx::IntSize& aSize, - GLenum aWrapMode, - ContentType aContentType, - GLContext* aContext, - TextureImage::Flags aFlags = TextureImage::NoFlags); - - ~TextureImageCGL(); - -protected: - bool FinishedSurfaceUpdate(); - - void FinishedSurfaceUpload(); - -private: - - GLuint mPixelBuffer; - bool mBoundPixelBuffer; -}; - -already_AddRefed<TextureImage> -CreateTextureImageCGL(GLContext* gl, - const gfx::IntSize& aSize, - TextureImage::ContentType aContentType, - GLenum aWrapMode, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat); - -already_AddRefed<TextureImage> -TileGenFuncCGL(GLContext* gl, - const gfx::IntSize& aSize, - TextureImage::ContentType aContentType, - TextureImage::Flags aFlags); - -} // namespace gl -} // namespace mozilla - -#endif
deleted file mode 100644 --- a/gfx/gl/TextureImageCGL.mm +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#include "TextureImageCGL.h" -#include "GLContext.h" -#include "gfx2DGlue.h" -#include "gfxQuartzSurface.h" -#include "gfxPlatform.h" -#include "gfxFailure.h" - -namespace mozilla { - -using namespace gfx; - -namespace gl { - -TextureImageCGL::TextureImageCGL(GLuint aTexture, - const IntSize& aSize, - GLenum aWrapMode, - ContentType aContentType, - GLContext* aContext, - TextureImage::Flags aFlags) - : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, - aContext, aFlags) - , mPixelBuffer(0) - , mBoundPixelBuffer(false) -{} - -TextureImageCGL::~TextureImageCGL() -{ - if (mPixelBuffer) { - mGLContext->MakeCurrent(); - mGLContext->fDeleteBuffers(1, &mPixelBuffer); - } -} - -bool -TextureImageCGL::FinishedSurfaceUpdate() -{ - if (mBoundPixelBuffer) { - mGLContext->MakeCurrent(); - mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer); - mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER); - return true; - } - return false; -} - -void -TextureImageCGL::FinishedSurfaceUpload() -{ - if (mBoundPixelBuffer) { - mGLContext->MakeCurrent(); - mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0); - mBoundPixelBuffer = false; - } -} - -already_AddRefed<TextureImage> -CreateTextureImageCGL(GLContext* gl, - const gfx::IntSize& aSize, - TextureImage::ContentType aContentType, - GLenum aWrapMode, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat) -{ - if (!gl->IsOffscreenSizeAllowed(aSize) && - gfxPlatform::OffMainThreadCompositingEnabled()) { - NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!"); - RefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType, - aFlags, aImageFormat); - return t.forget(); - } - - return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, - aFlags); -} - -already_AddRefed<TextureImage> -TileGenFuncCGL(GLContext* gl, - const IntSize& aSize, - TextureImage::ContentType aContentType, - TextureImage::Flags aFlags) -{ - bool useNearestFilter = aFlags & TextureImage::UseNearestFilter; - gl->MakeCurrent(); - - GLuint texture; - gl->fGenTextures(1, &texture); - - gl->fActiveTexture(LOCAL_GL_TEXTURE0); - gl->fBindTexture(LOCAL_GL_TEXTURE_2D, texture); - - GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR; - gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter); - gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter); - 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); - - RefPtr<TextureImageCGL> teximage - (new TextureImageCGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, - gl, aFlags)); - return teximage.forget(); -} - -} // namespace gl -} // namespace mozilla
--- a/gfx/gl/TextureImageEGL.cpp +++ b/gfx/gl/TextureImageEGL.cpp @@ -90,115 +90,16 @@ TextureImageEGL::~TextureImageEGL() // was the only one that had access to it. if (mGLContext->MakeCurrent()) { mGLContext->fDeleteTextures(1, &mTexture); } ReleaseTexImage(); DestroyEGLSurface(); } -void -TextureImageEGL::GetUpdateRegion(nsIntRegion& aForRegion) -{ - if (mTextureState != Valid) { - // if the texture hasn't been initialized yet, force the - // client to paint everything - aForRegion = gfx::IntRect(gfx::IntPoint(0, 0), mSize); - } - - // We can only draw a rectangle, not subregions due to - // the way that our texture upload functions work. If - // needed, we /could/ do multiple texture uploads if we have - // non-overlapping rects, but that's a tradeoff. - aForRegion = nsIntRegion(aForRegion.GetBounds()); -} - -gfx::DrawTarget* -TextureImageEGL::BeginUpdate(nsIntRegion& aRegion) -{ - NS_ASSERTION(!mUpdateDrawTarget, "BeginUpdate() without EndUpdate()?"); - - // determine the region the client will need to repaint - GetUpdateRegion(aRegion); - mUpdateRect = aRegion.GetBounds(); - - //printf_stderr("BeginUpdate with updateRect [%d %d %d %d]\n", mUpdateRect.x, mUpdateRect.y, mUpdateRect.width, mUpdateRect.height); - if (!gfx::IntRect(gfx::IntPoint(0, 0), mSize).Contains(mUpdateRect)) { - NS_ERROR("update outside of image"); - return nullptr; - } - - //printf_stderr("creating image surface %dx%d format %d\n", mUpdateRect.width, mUpdateRect.height, mUpdateFormat); - - mUpdateDrawTarget = gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO, - gfx::IntSize(mUpdateRect.width, mUpdateRect.height), - mUpdateFormat); - - return mUpdateDrawTarget; -} - -void -TextureImageEGL::EndUpdate() -{ - NS_ASSERTION(!!mUpdateDrawTarget, "EndUpdate() without BeginUpdate()?"); - - //printf_stderr("EndUpdate: slow path"); - - // This is the slower path -- we didn't have any way to set up - // a fast mapping between our cairo target surface and the GL - // texture, so we have to upload data. - - RefPtr<gfx::SourceSurface> updateSurface = nullptr; - RefPtr<gfx::DataSourceSurface> uploadImage = nullptr; - gfx::IntSize updateSize(mUpdateRect.width, mUpdateRect.height); - - NS_ASSERTION(mUpdateDrawTarget->GetSize() == updateSize, - "Upload image is the wrong size!"); - - updateSurface = mUpdateDrawTarget->Snapshot(); - uploadImage = updateSurface->GetDataSurface(); - - if (!uploadImage) { - return; - } - - mGLContext->MakeCurrent(); - mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); - - if (mTextureState != Valid) { - NS_ASSERTION(mUpdateRect.x == 0 && mUpdateRect.y == 0 && - mUpdateRect.Size() == mSize, - "Bad initial update on non-created texture!"); - - mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, - 0, - GLFormatForImage(mUpdateFormat), - mUpdateRect.width, - mUpdateRect.height, - 0, - GLFormatForImage(uploadImage->GetFormat()), - GLTypeForImage(uploadImage->GetFormat()), - uploadImage->GetData()); - } else { - mGLContext->fTexSubImage2D(LOCAL_GL_TEXTURE_2D, - 0, - mUpdateRect.x, - mUpdateRect.y, - mUpdateRect.width, - mUpdateRect.height, - GLFormatForImage(uploadImage->GetFormat()), - GLTypeForImage(uploadImage->GetFormat()), - uploadImage->GetData()); - } - - mUpdateDrawTarget = nullptr; - mTextureState = Valid; - return; // mTexture is bound -} - bool TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0,0) */) { gfx::IntRect bounds = aRegion.GetBounds(); nsIntRegion region; if (mTextureState != Valid) { bounds = gfx::IntRect(0, 0, mSize.width, mSize.height); @@ -237,18 +138,16 @@ TextureImageEGL::BindTexture(GLenum aTex mGLContext->fActiveTexture(aTextureUnit); mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0); } void TextureImageEGL::Resize(const gfx::IntSize& aSize) { - NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?"); - if (mSize == aSize && mTextureState != Created) return; mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, GLFormatForImage(mUpdateFormat),
--- a/gfx/gl/TextureImageEGL.h +++ b/gfx/gl/TextureImageEGL.h @@ -21,37 +21,29 @@ public: ContentType aContentType, GLContext* aContext, Flags aFlags = TextureImage::NoFlags, TextureState aTextureState = Created, TextureImage::ImageFormat aImageFormat = SurfaceFormat::UNKNOWN); virtual ~TextureImageEGL(); - virtual void GetUpdateRegion(nsIntRegion& aForRegion); - - virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion); - - virtual void EndUpdate(); - virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)); virtual void BindTexture(GLenum aTextureUnit); virtual GLuint GetTextureID() { // Ensure the texture is allocated before it is used. if (mTextureState == Created) { Resize(mSize); } return mTexture; }; - virtual bool InUpdate() const { return !!mUpdateDrawTarget; } - virtual void Resize(const gfx::IntSize& aSize); bool BindTexImage(); bool ReleaseTexImage(); virtual bool CreateEGLSurface(gfxASurface* aSurface) { @@ -60,19 +52,17 @@ public: virtual void DestroyEGLSurface(void); protected: typedef gfxImageFormat ImageFormat; GLContext* mGLContext; - gfx::IntRect mUpdateRect; gfx::SurfaceFormat mUpdateFormat; - RefPtr<gfx::DrawTarget> mUpdateDrawTarget; EGLImage mEGLImage; GLuint mTexture; EGLSurface mSurface; EGLConfig mConfig; TextureState mTextureState; bool mBound; };
--- a/gfx/gl/moz.build +++ b/gfx/gl/moz.build @@ -89,17 +89,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk EXPORTS += ['SharedSurfaceGralloc.h'] LOCAL_INCLUDES += ['/widget/gonk'] LOCAL_INCLUDES += ['%' + '%s/%s' % (CONFIG['ANDROID_SOURCE'], 'hardware/libhardware/include')] if gl_provider == 'CGL': # These files include Mac headers that are unfriendly to unified builds SOURCES += [ "GLContextProviderCGL.mm", - "TextureImageCGL.mm" ] EXPORTS += [ 'GLContextCGL.h', 'SharedSurfaceIO.h', ] # SharedSurfaceIO.cpp includes MacIOSurface.h which include Mac headers # which define Size and Point types in root namespace with often conflict with # our own types. While I haven't actually hit this issue in the present case,
--- a/gfx/layers/opengl/GLBlitTextureImageHelper.cpp +++ b/gfx/layers/opengl/GLBlitTextureImageHelper.cpp @@ -37,18 +37,16 @@ GLBlitTextureImageHelper::~GLBlitTexture gl->fDeleteFramebuffers(1, &mBlitFramebuffer); } void GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const gfx::IntRect& aSrcRect, TextureImage *aDst, const gfx::IntRect& aDstRect) { GLContext *gl = mCompositor->gl(); - NS_ASSERTION(!aSrc->InUpdate(), "Source texture is in update!"); - NS_ASSERTION(!aDst->InUpdate(), "Destination texture is in update!"); if (!aSrc || !aDst || aSrcRect.IsEmpty() || aDstRect.IsEmpty()) return; int savedFb = 0; gl->fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &savedFb); ScopedGLState scopedScissorTestState(gl, LOCAL_GL_SCISSOR_TEST, false);
--- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -188,19 +188,16 @@ TextureImageTextureSourceOGL::Update(gfx // allocation (full size, but no upload), and then we'll only upload the pixels // we care about below. mTexImage->Resize(size); } } mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset); - if (mTexImage->InUpdate()) { - mTexImage->EndUpdate(); - } return true; } void TextureImageTextureSourceOGL::EnsureBuffer(const IntSize& aSize, gfxContentType aContentType) { if (!mTexImage ||