author | Benoit Jacob <bjacob@mozilla.com> |
Tue, 03 Dec 2013 13:44:38 -0500 | |
changeset 158632 | 7c7c405d9373a0ae722411613b841161bbbfc86d |
parent 158631 | 11d9777debba413f62c1c16dc8c91eab70789cb2 |
child 158633 | 22a1c5c1371632d71b0babaa0d908172a8fb8069 |
push id | 25752 |
push user | cbook@mozilla.com |
push date | Wed, 04 Dec 2013 08:35:03 +0000 |
treeherder | mozilla-central@8187818246ad [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | BenWa |
bugs | 942499 |
milestone | 28.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/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -1140,42 +1140,16 @@ GLContext::InitExtensions() MarkExtensionSupported(OES_rgb8_rgba8); } #ifdef DEBUG firstRun = false; #endif } -// In both of these cases (for the Adreno at least) it is impossible -// to determine good or bad driver versions for POT texture uploads, -// so blacklist them all. Newer drivers use a different rendering -// string in the form "Adreno (TM) 200" and the drivers we've seen so -// far work fine with NPOT textures, so don't blacklist those until we -// have evidence of any problems with them. -bool -GLContext::CanUploadSubTextures() -{ - if (!mWorkAroundDriverBugs) - return true; - - // There are certain GPUs that we don't want to use glTexSubImage2D on - // because that function can be very slow and/or buggy - if (Renderer() == RendererAdreno200 || Renderer() == RendererAdreno205) - return false; - - // On PowerVR glTexSubImage does a readback, so it will be slower - // than just doing a glTexImage2D() directly. i.e. 26ms vs 10ms - if (Renderer() == RendererSGX540 || Renderer() == RendererSGX530) - return false; - - return true; -} - - bool GLContext::CanReadSRGBFromFBOTexture() { if (!mWorkAroundDriverBugs) return true; #ifdef XP_MACOSX // Bug 843668: @@ -1222,34 +1196,16 @@ GLContext::CanUploadNonPowerOfTwo() if (!mWorkAroundDriverBugs) return true; // Some GPUs driver crash when uploading non power of two 565 textures. return sPowerOfTwoForced ? false : (Renderer() != RendererAdreno200 && Renderer() != RendererAdreno205); } -bool -GLContext::WantsSmallTiles() -{ - // We must use small tiles for good performance if we can't use - // glTexSubImage2D() for some reason. - if (!CanUploadSubTextures()) - return true; - - // We can't use small tiles on the SGX 540, because of races in texture upload. - if (mWorkAroundDriverBugs && - Renderer() == RendererSGX540) - return false; - - // Don't use small tiles otherwise. (If we implement incremental texture upload, - // then we will want to revisit this.) - return false; -} - // Common code for checking for both GL extensions and GLX extensions. bool GLContext::ListHasExtension(const GLubyte *extensions, const char *extension) { // fix bug 612572 - we were crashing as we were calling this function with extensions==null if (extensions == nullptr || extension == nullptr) return false;
--- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -2468,31 +2468,28 @@ public: * * If surf is null, this removes any previously set override, and makes the * context current again against its primary surface. */ virtual void SetEGLSurfaceOverride(EGLSurface surf) { MOZ_CRASH("Must be called against a GLContextEGL."); } - bool CanUploadSubTextures(); bool CanReadSRGBFromFBOTexture(); static void PlatformStartup(); protected: static bool sPowerOfTwoForced; static bool sPowerOfTwoPrefCached; static void CacheCanUploadNPOT(); public: bool CanUploadNonPowerOfTwo(); - bool WantsSmallTiles(); - /** * If this context wraps a double-buffered target, swap the back * and front buffers. It should be assumed that after a swap, the * contents of the new back buffer are undefined. */ virtual bool SwapBuffers() { return false; } /**
--- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -125,17 +125,17 @@ BasicTextureImage::~BasicTextureImage() } gfxASurface* BasicTextureImage::BeginUpdate(nsIntRegion& aRegion) { NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?"); // determine the region the client will need to repaint - if (mGLContext->CanUploadSubTextures()) { + if (CanUploadSubTextures(mGLContext)) { GetUpdateRegion(aRegion); } else { aRegion = nsIntRect(nsIntPoint(0, 0), mSize); } mUpdateRegion = aRegion; nsIntRect rgnSize = mUpdateRegion.GetBounds(); @@ -328,32 +328,50 @@ CreateBasicTextureImage(GLContext* aGL, const gfx::IntSize& aSize, TextureImage::ContentType aContentType, GLenum aWrapMode, TextureImage::Flags aFlags) { return CreateBasicTextureImage(aGL, ThebesIntSize(aSize), aContentType, aWrapMode, aFlags); } +static bool +WantsSmallTiles(GLContext* gl) +{ + // We must use small tiles for good performance if we can't use + // glTexSubImage2D() for some reason. + if (!CanUploadSubTextures(gl)) + return true; + + // We can't use small tiles on the SGX 540, because of races in texture upload. + if (gl->WorkAroundDriverBugs() && + gl->Renderer() == GLContext::RendererSGX540) + return false; + + // Don't use small tiles otherwise. (If we implement incremental texture upload, + // then we will want to revisit this.) + return false; +} + TiledTextureImage::TiledTextureImage(GLContext* aGL, nsIntSize aSize, TextureImage::ContentType aContentType, TextureImage::Flags aFlags, TextureImage::ImageFormat aImageFormat) : TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aFlags) , mCurrentImage(0) , mIterationCallback(nullptr) , mInUpdate(false) , mRows(0) , mColumns(0) , mGL(aGL) , mTextureState(Created) , mImageFormat(aImageFormat) { - if (!(aFlags & TextureImage::DisallowBigImage) && mGL->WantsSmallTiles()) { + if (!(aFlags & TextureImage::DisallowBigImage) && WantsSmallTiles(mGL)) { mTileSize = 256; } else { mGL->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, (GLint*) &mTileSize); } if (aSize.width != 0 && aSize.height != 0) { Resize(aSize); } } @@ -387,17 +405,17 @@ TiledTextureImage::DirectUpdate(gfxASurf int yPos = tileRect.y; nsIntRegion tileRegion; tileRegion.And(region, tileRect); // intersect with tile if (tileRegion.IsEmpty()) continue; - if (mGL->CanUploadSubTextures()) { + if (CanUploadSubTextures(mGL)) { tileRegion.MoveBy(-xPos, -yPos); // translate into tile local space } else { // If sub-textures are unsupported, expand to tile boundaries tileRect.x = tileRect.y = 0; tileRegion = nsIntRegion(tileRect); } result &= mImages[mCurrentImage]->
--- a/gfx/gl/GLUploadHelpers.cpp +++ b/gfx/gl/GLUploadHelpers.cpp @@ -87,16 +87,47 @@ CopyAndPadTextureData(const GLvoid* srcB rowDest = static_cast<unsigned char*>(dstBuffer) + srcWidth * pixelsize; for (GLsizei h = 0; h < padHeight; ++h) { memcpy(rowDest, rowDest - pixelsize, pixelsize); rowDest += dstWidth * pixelsize; } } } +// In both of these cases (for the Adreno at least) it is impossible +// to determine good or bad driver versions for POT texture uploads, +// so blacklist them all. Newer drivers use a different rendering +// string in the form "Adreno (TM) 200" and the drivers we've seen so +// far work fine with NPOT textures, so don't blacklist those until we +// have evidence of any problems with them. +bool +CanUploadSubTextures(GLContext* gl) +{ + if (!gl->WorkAroundDriverBugs()) + return true; + + // There are certain GPUs that we don't want to use glTexSubImage2D on + // because that function can be very slow and/or buggy + if (gl->Renderer() == GLContext::RendererAdreno200 || + gl->Renderer() == GLContext::RendererAdreno205) + { + return false; + } + + // On PowerVR glTexSubImage does a readback, so it will be slower + // than just doing a glTexImage2D() directly. i.e. 26ms vs 10ms + if (gl->Renderer() == GLContext::RendererSGX540 || + gl->Renderer() == GLContext::RendererSGX530) + { + return false; + } + + return true; +} + static void TexSubImage2DWithUnpackSubimageGLES(GLContext* gl, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei stride, GLint pixelsize, GLenum format, GLenum type, const GLvoid* pixels) @@ -441,17 +472,17 @@ UploadImageDataToTexture(GLContext* gl, // 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(iterRect->TopLeft() - topLeft, aStride, aFormat); NS_ASSERTION(textureInited || (iterRect->x == 0 && iterRect->y == 0), "Must be uploading to the origin when we don't have an existing texture"); - if (textureInited && gl->CanUploadSubTextures()) { + if (textureInited && CanUploadSubTextures(gl)) { TexSubImage2DHelper(gl, aTextureTarget, 0, iterRect->x, iterRect->y, iterRect->width, iterRect->height, aStride,
--- a/gfx/gl/GLUploadHelpers.h +++ b/gfx/gl/GLUploadHelpers.h @@ -90,12 +90,14 @@ UploadSurfaceToTexture(GLContext* gl, const nsIntRegion& aDstRegion, GLuint& aTexture, bool aOverwrite, const nsIntPoint& aSrcPoint, bool aPixelBuffer, GLenum aTextureUnit, GLenum aTextureTarget); +bool CanUploadSubTextures(GLContext* gl); + } } #endif
--- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -5,16 +5,17 @@ #include "CompositorOGL.h" #include <stddef.h> // for size_t #include <stdint.h> // for uint32_t, uint8_t #include <stdlib.h> // for free, malloc #include "FPSCounter.h" // for FPSState, FPSCounter #include "GLContextProvider.h" // for GLContextProvider #include "GLContext.h" // for GLContext +#include "GLUploadHelpers.h" #include "Layers.h" // for WriteSnapshotToDumpFile #include "LayerScope.h" // for LayerScope #include "gfx2DGlue.h" // for ThebesFilter #include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxASurface.h" // for gfxASurface, etc #include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter #include "gfxImageSurface.h" // for gfxImageSurface #include "gfxMatrix.h" // for gfxMatrix @@ -1496,17 +1497,17 @@ CompositorOGL::CreateDataTextureSource(T new TextureImageTextureSourceOGL(mGLContext, !(aFlags & TEXTURE_DISALLOW_BIGIMAGE)); return result; } bool CompositorOGL::SupportsPartialTextureUpdate() { - return mGLContext->CanUploadSubTextures(); + return CanUploadSubTextures(mGLContext); } int32_t CompositorOGL::GetMaxTextureSize() const { MOZ_ASSERT(mGLContext); GLint texSize = 0; mGLContext->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE,