author | James Willcox <snorp@snorp.net> |
Wed, 03 Feb 2016 14:44:12 -0600 | |
changeset 319279 | d02a1e213646365333a184cc7da860c0d3da16ff |
parent 319278 | 6aa232d721699891e2734f83e51267848de69707 |
child 319280 | 9b261217646ee945aa5d0bfbce0e005f922a76c4 |
push id | 5913 |
push user | jlund@mozilla.com |
push date | Mon, 25 Apr 2016 16:57:49 +0000 |
treeherder | mozilla-beta@dcaf0a6fa115 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1243072 |
milestone | 47.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
|
--- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -7,17 +7,16 @@ #include "GLContext.h" #include "gfxContext.h" #include "gfxPlatform.h" #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; @@ -91,26 +90,16 @@ TextureImage::UpdateFromDataSource(gfx:: gfx::IntRect TextureImage::GetTileRect() { return gfx::IntRect(gfx::IntPoint(0,0), mSize); } gfx::IntRect TextureImage::GetSrcTileRect() { return GetTileRect(); } -void -TextureImage::UpdateUploadSize(size_t amount) -{ - if (mUploadSize > 0) { - GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryFreed, mUploadSize); - } - mUploadSize = amount; - GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryAllocated, mUploadSize); -} - BasicTextureImage::~BasicTextureImage() { GLContext *ctx = mGLContext; if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) { ctx = ctx->GetSharedContext(); } // If we have a context, then we need to delete the texture; @@ -168,30 +157,26 @@ 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(); - size_t uploadSize; + mTextureFormat = UploadSurfaceToTexture(mGLContext, updateData, mUpdateRegion, mTexture, - &uploadSize, mTextureState == Created, mUpdateOffset, relative); FinishedSurfaceUpload(); - if (uploadSize > 0) { - UpdateUploadSize(uploadSize); - } mUpdateDrawTarget = nullptr; mTextureState = Valid; } void BasicTextureImage::BindTexture(GLenum aTextureUnit) { @@ -224,29 +209,24 @@ BasicTextureImage::DirectUpdate(gfx::Dat nsIntRegion region; if (mTextureState != Valid) { bounds = IntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); } else { region = aRegion; } - size_t uploadSize; mTextureFormat = UploadSurfaceToTexture(mGLContext, aSurf, region, mTexture, - &uploadSize, mTextureState == Created, bounds.TopLeft() + IntPoint(aFrom.x, aFrom.y), false); - if (uploadSize > 0) { - UpdateUploadSize(uploadSize); - } mTextureState = Valid; return true; } void BasicTextureImage::Resize(const gfx::IntSize& aSize) { NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?"); @@ -288,17 +268,16 @@ TextureImage::TextureImage(const gfx::In GLenum aWrapMode, ContentType aContentType, Flags aFlags) : mSize(aSize) , mWrapMode(aWrapMode) , mContentType(aContentType) , mTextureFormat(gfx::SurfaceFormat::UNKNOWN) , mFilter(Filter::GOOD) , mFlags(aFlags) - , mUploadSize(0) {} BasicTextureImage::BasicTextureImage(GLuint aTexture, const gfx::IntSize& aSize, GLenum aWrapMode, ContentType aContentType, GLContext* aContext, TextureImage::Flags aFlags)
--- a/gfx/gl/GLTextureImage.h +++ b/gfx/gl/GLTextureImage.h @@ -198,42 +198,37 @@ public: virtual bool InUpdate() const = 0; GLenum GetWrapMode() const { return mWrapMode; } void SetFilter(gfx::Filter aFilter) { mFilter = aFilter; } protected: friend class GLContext; - void UpdateUploadSize(size_t amount); - /** * After the ctor, the TextureImage is invalid. Implementations * must allocate resources successfully before returning the new * TextureImage from GLContext::CreateTextureImage(). That is, * clients must not be given partially-constructed TextureImages. */ TextureImage(const gfx::IntSize& aSize, GLenum aWrapMode, ContentType aContentType, Flags aFlags = NoFlags); // Protected destructor, to discourage deletion outside of Release(): - virtual ~TextureImage() { - UpdateUploadSize(0); - } + virtual ~TextureImage() {} virtual gfx::IntRect GetSrcTileRect(); gfx::IntSize mSize; GLenum mWrapMode; ContentType mContentType; gfx::SurfaceFormat mTextureFormat; gfx::Filter mFilter; Flags mFlags; - size_t mUploadSize; }; /** * BasicTextureImage is the baseline TextureImage implementation --- * it updates its texture by allocating a scratch buffer for the * client to draw into, then using glTexSubImage2D() to upload the new * pixels. Platforms must provide the code to create a new surface * into which the updated pixels will be drawn, and the code to
--- a/gfx/gl/GLUploadHelpers.cpp +++ b/gfx/gl/GLUploadHelpers.cpp @@ -4,17 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GLUploadHelpers.h" #include "GLContext.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Tools.h" // For BytesPerPixel #include "nsRegion.h" -#include "GfxTexturesReporter.h" namespace mozilla { using namespace gfx; namespace gl { /* These two techniques are suggested by "Bit Twiddling Hacks" @@ -375,68 +374,23 @@ TexImage2DHelper(GLContext *gl, format, type, pixels); gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0); gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4); } } -static uint32_t -GetBytesPerTexel(GLenum format, GLenum type) -{ - // If there is no defined format or type, we're not taking up any memory - if (!format || !type) { - return 0; - } - - if (format == LOCAL_GL_DEPTH_COMPONENT) { - if (type == LOCAL_GL_UNSIGNED_SHORT) - return 2; - else if (type == LOCAL_GL_UNSIGNED_INT) - return 4; - } else if (format == LOCAL_GL_DEPTH_STENCIL) { - if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT) - return 4; - } - - if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) { - uint32_t multiplier = type == LOCAL_GL_FLOAT ? 4 : 1; - switch (format) { - case LOCAL_GL_ALPHA: - case LOCAL_GL_LUMINANCE: - return 1 * multiplier; - case LOCAL_GL_LUMINANCE_ALPHA: - return 2 * multiplier; - case LOCAL_GL_RGB: - return 3 * multiplier; - case LOCAL_GL_RGBA: - return 4 * multiplier; - default: - break; - } - } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 || - type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || - type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) - { - return 2; - } - - MOZ_RELEASE_ASSERT(false, "Unknown type and/or format"); - return 0; -} - SurfaceFormat UploadImageDataToTexture(GLContext* gl, unsigned char* aData, int32_t aStride, SurfaceFormat aFormat, const nsIntRegion& aDstRegion, GLuint& aTexture, - size_t* aOutUploadSize, bool aOverwrite, bool aPixelBuffer, GLenum aTextureUnit, GLenum aTextureTarget) { bool textureInited = aOverwrite ? false : true; gl->MakeCurrent(); gl->fActiveTexture(aTextureUnit); @@ -546,20 +500,16 @@ UploadImageDataToTexture(GLContext* gl, default: NS_ASSERTION(false, "Unhandled image surface format!"); } // Top left point of the region's bounding rectangle. IntPoint topLeft = paintRegion.GetBounds().TopLeft(); - if (aOutUploadSize) { - *aOutUploadSize = 0; - } - for (auto iter = paintRegion.RectIter(); !iter.Done(); iter.Next()) { const IntRect& rect = iter.Get(); // The inital data pointer is at the top left point of the region's // bounding rectangle. We need to find the offset of this rect // within the region and adjust the data pointer accordingly. unsigned char *rectData = aData + DataOffset(rect.TopLeft() - topLeft, aStride, aFormat); @@ -589,45 +539,39 @@ UploadImageDataToTexture(GLContext* gl, aStride, pixelSize, 0, format, type, rectData); } - if (aOutUploadSize && !textureInited) { - uint32_t texelSize = GetBytesPerTexel(internalFormat, type); - size_t numTexels = size_t(rect.width) * size_t(rect.height); - *aOutUploadSize += texelSize * numTexels; - } } return surfaceFormat; } SurfaceFormat UploadSurfaceToTexture(GLContext* gl, - DataSourceSurface* aSurface, + DataSourceSurface *aSurface, const nsIntRegion& aDstRegion, GLuint& aTexture, - size_t* aOutUploadSize, bool aOverwrite, const gfx::IntPoint& aSrcPoint, bool aPixelBuffer, GLenum aTextureUnit, GLenum aTextureTarget) { unsigned char* data = aPixelBuffer ? nullptr : aSurface->GetData(); int32_t stride = aSurface->Stride(); SurfaceFormat format = aSurface->GetFormat(); data += DataOffset(aSrcPoint, stride, format); return UploadImageDataToTexture(gl, data, stride, format, - aDstRegion, aTexture, aOutUploadSize, - aOverwrite, aPixelBuffer, aTextureUnit, + aDstRegion, aTexture, aOverwrite, + aPixelBuffer, aTextureUnit, aTextureTarget); } bool CanUploadNonPowerOfTwo(GLContext* gl) { if (!gl->WorkAroundDriverBugs()) return true;
--- a/gfx/gl/GLUploadHelpers.h +++ b/gfx/gl/GLUploadHelpers.h @@ -35,17 +35,16 @@ class GLContext; * texture memory block allocated. * * The aDstPoint parameter is ignored if no texture was provided * or aOverwrite is true. * * \param aData Image data to upload. * \param aDstRegion Region of texture to upload to. * \param aTexture Texture to use, or 0 to have one created for you. - * \param aOutUploadSize if set, the number of bytes the texture requires will be returned here * \param aOverwrite Over an existing texture with a new one. * \param aSrcPoint Offset into aSrc where the region's bound's * TopLeft() sits. * \param aPixelBuffer Pass true to upload texture data with an * offset from the base data (generally for pixel buffer objects), * otherwise textures are upload with an absolute pointer to the data. * \param aTextureUnit, the texture unit used temporarily to upload the * surface. This testure may be overridden, clients should not rely on @@ -55,31 +54,29 @@ class GLContext; */ gfx::SurfaceFormat UploadImageDataToTexture(GLContext* gl, unsigned char* aData, int32_t aStride, gfx::SurfaceFormat aFormat, const nsIntRegion& aDstRegion, GLuint& aTexture, - size_t* aOutUploadSize = nullptr, bool aOverwrite = false, bool aPixelBuffer = false, GLenum aTextureUnit = LOCAL_GL_TEXTURE0, GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D); /** * Convenience wrapper around UploadImageDataToTexture for gfx::DataSourceSurface's. */ gfx::SurfaceFormat UploadSurfaceToTexture(GLContext* gl, gfx::DataSourceSurface *aSurface, const nsIntRegion& aDstRegion, GLuint& aTexture, - size_t* aOutUploadSize = nullptr, bool aOverwrite = false, const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0), bool aPixelBuffer = false, GLenum aTextureUnit = LOCAL_GL_TEXTURE0, GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D); bool CanUploadSubTextures(GLContext* gl); bool CanUploadNonPowerOfTwo(GLContext* gl);
--- a/gfx/gl/GfxTexturesReporter.cpp +++ b/gfx/gl/GfxTexturesReporter.cpp @@ -1,26 +1,99 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* vim: set ts=8 sts=4 et sw=4 tw=80: */ /* 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 "GfxTexturesReporter.h" +#include "GLDefs.h" using namespace mozilla; using namespace mozilla::gl; NS_IMPL_ISUPPORTS(GfxTexturesReporter, nsIMemoryReporter) -Atomic<size_t> GfxTexturesReporter::sAmount(0); -Atomic<size_t> GfxTexturesReporter::sTileWasteAmount(0); +Atomic<int32_t> GfxTexturesReporter::sAmount(0); +Atomic<int32_t> GfxTexturesReporter::sTileWasteAmount(0); + +static uint32_t +GetBitsPerTexel(GLenum format, GLenum type) +{ + // If there is no defined format or type, we're not taking up any memory + if (!format || !type) { + return 0; + } + + if (format == LOCAL_GL_DEPTH_COMPONENT) { + if (type == LOCAL_GL_UNSIGNED_SHORT) + return 2*8; + else if (type == LOCAL_GL_UNSIGNED_INT) + return 4*8; + } else if (format == LOCAL_GL_DEPTH_STENCIL) { + if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT) + return 4*8; + } + + if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) { + uint32_t multiplier = type == LOCAL_GL_FLOAT ? 32 : 8; + switch (format) { + case LOCAL_GL_ALPHA: + case LOCAL_GL_LUMINANCE: + return 1 * multiplier; + case LOCAL_GL_LUMINANCE_ALPHA: + return 2 * multiplier; + case LOCAL_GL_RGB: + return 3 * multiplier; + case LOCAL_GL_RGBA: + return 4 * multiplier; + case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1: + case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1: + return 2; + case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case LOCAL_GL_ATC_RGB: + case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1: + case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1: + case LOCAL_GL_ETC1_RGB8_OES: + case LOCAL_GL_COMPRESSED_RGB8_ETC2: + case LOCAL_GL_COMPRESSED_SRGB8_ETC2: + case LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case LOCAL_GL_COMPRESSED_R11_EAC: + case LOCAL_GL_COMPRESSED_SIGNED_R11_EAC: + return 4; + case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA: + case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA: + case LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC: + case LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case LOCAL_GL_COMPRESSED_RG11_EAC: + case LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC: + return 8; + default: + break; + } + } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 || + type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || + type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) + { + return 2*8; + } + + MOZ_ASSERT(false); + return 0; +} /* static */ void -GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount) +GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format, + GLenum type, int32_t tileWidth, + int32_t tileHeight) { + int64_t bitsPerTexel = GetBitsPerTexel(format, type); + int64_t bytes = int64_t(tileWidth) * int64_t(tileHeight) * bitsPerTexel/8; if (action == MemoryFreed) { - MOZ_RELEASE_ASSERT(amount <= sAmount); - sAmount -= amount; + sAmount -= bytes; } else { - sAmount += amount; + sAmount += bytes; } }
--- a/gfx/gl/GfxTexturesReporter.h +++ b/gfx/gl/GfxTexturesReporter.h @@ -36,37 +36,38 @@ public: // when memory being allocated is reported to a memory reporter MemoryAllocated, // when memory being freed is reported to a memory reporter MemoryFreed }; // When memory is used/freed for tile textures, call this method to update // the value reported by this memory reporter. - static void UpdateAmount(MemoryUse action, size_t amount); + static void UpdateAmount(MemoryUse action, GLenum format, GLenum type, + int32_t tileWidth, int32_t tileHeight); - static void UpdateWasteAmount(size_t delta) { + static void UpdateWasteAmount(int32_t delta) { sTileWasteAmount += delta; } NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) override { MOZ_COLLECT_REPORT("gfx-tiles-waste", KIND_OTHER, UNITS_BYTES, - int64_t(sTileWasteAmount), + sTileWasteAmount, "Memory lost due to tiles extending past content boundaries"); return MOZ_COLLECT_REPORT( - "gfx-textures", KIND_OTHER, UNITS_BYTES, int64_t(sAmount), + "gfx-textures", KIND_OTHER, UNITS_BYTES, sAmount, "Memory used for storing GL textures."); } private: - static Atomic<size_t> sAmount; + static Atomic<int32_t> sAmount; // Count the amount of memory lost to tile waste - static Atomic<size_t> sTileWasteAmount; + static Atomic<int32_t> sTileWasteAmount; }; class GfxTextureWasteTracker { public: GfxTextureWasteTracker() : mBytes(0) { MOZ_COUNT_CTOR(GfxTextureWasteTracker);
--- a/gfx/gl/TextureImageEGL.cpp +++ b/gfx/gl/TextureImageEGL.cpp @@ -202,29 +202,24 @@ TextureImageEGL::DirectUpdate(gfx::DataS nsIntRegion region; if (mTextureState != Valid) { bounds = gfx::IntRect(0, 0, mSize.width, mSize.height); region = nsIntRegion(bounds); } else { region = aRegion; } - size_t uploadSize = 0; mTextureFormat = UploadSurfaceToTexture(mGLContext, aSurf, region, mTexture, - &uploadSize, mTextureState == Created, bounds.TopLeft() + gfx::IntPoint(aFrom.x, aFrom.y), false); - if (uploadSize > 0) { - UpdateUploadSize(uploadSize); - } mTextureState = Valid; return true; } void TextureImageEGL::BindTexture(GLenum aTextureUnit) {