diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-20 19:22:38 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-08-20 19:22:38 +0000 |
commit | 0342a85091fd430c90a142d155dc9642aa729d9e (patch) | |
tree | ad84edb6b6194b35ca77783c7147c2e62a56542f | |
parent | b7961193a3ecca44cf2650d9e446ebaa10b1583d (diff) |
Remove _UPM_ GrPixelConfigs
Review URL: http://codereview.appspot.com/6460113/
git-svn-id: http://skia.googlecode.com/svn/trunk@5196 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/gpu/GrContext.h | 116 | ||||
-rw-r--r-- | include/gpu/GrRenderTarget.h | 38 | ||||
-rw-r--r-- | include/gpu/GrSamplerState.h | 9 | ||||
-rw-r--r-- | include/gpu/GrSurface.h | 32 | ||||
-rw-r--r-- | include/gpu/GrTexture.h | 39 | ||||
-rw-r--r-- | include/gpu/GrTypes.h | 78 | ||||
-rw-r--r-- | src/gpu/GrAtlas.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 164 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 9 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 23 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrRenderTarget.cpp | 24 | ||||
-rw-r--r-- | src/gpu/GrTexture.cpp | 16 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 36 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.cpp | 14 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 33 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 4 | ||||
-rw-r--r-- | tests/PremulAlphaRoundTripTest.cpp | 7 |
20 files changed, 274 insertions, 390 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 0687dcf7b5..dbb404ffe9 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -465,54 +465,60 @@ public: */ void flush(int flagsBitfield = 0); + /** + * These flags can be used with the read/write pixels functions below. + */ + enum PixelOpsFlags { + /** The GrContext will not be flushed. This means that the read or write may occur before + previous draws have executed. */ + kDontFlush_PixelOpsFlag = 0x1, + /** The src for write or dst read is unpremultiplied. This is only respected if both the + config src and dst configs are an RGBA/BGRA 8888 format. */ + kUnpremul_PixelOpsFlag = 0x2, + }; + /** * Reads a rectangle of pixels from a render target. - * @param target the render target to read from. NULL means the - * current render target. + * @param target the render target to read from. NULL means the current render target. * @param left left edge of the rectangle to read (inclusive) * @param top top edge of the rectangle to read (inclusive) * @param width width of rectangle to read in pixels. * @param height height of rectangle to read in pixels. * @param config the pixel config of the destination buffer * @param buffer memory to read the rectangle into. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. * - * @return true if the read succeeded, false if not. The read can fail - * because of an unsupported pixel config or because no render - * target is currently set. + * @return true if the read succeeded, false if not. The read can fail because of an unsupported + * pixel config or because no render target is currently set and NULL was passed for + * target. */ bool readRenderTargetPixels(GrRenderTarget* target, int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes) { - return this->internalReadRenderTargetPixels(target, left, top, - width, height, - config, buffer, - rowBytes, 0); - } + GrPixelConfig config, void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); /** - * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target - * at the specified rectangle. - * @param target the render target to write into. NULL means the - * current render target. + * Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target at the specified + * rectangle. + * @param target the render target to write into. NULL means the current render target. * @param left left edge of the rectangle to write (inclusive) * @param top top edge of the rectangle to write (inclusive) * @param width width of rectangle to write in pixels. * @param height height of rectangle to write in pixels. * @param config the pixel config of the source buffer * @param buffer memory to read the rectangle from. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. */ void writeRenderTargetPixels(GrRenderTarget* target, int left, int top, int width, int height, GrPixelConfig config, const void* buffer, - size_t rowBytes) { - this->internalWriteRenderTargetPixels(target, left, top, width, height, - config, buffer, rowBytes, 0); - } + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); /** * Reads a rectangle of pixels from a texture. @@ -523,20 +529,18 @@ public: * @param height height of rectangle to read in pixels. * @param config the pixel config of the destination buffer * @param buffer memory to read the rectangle into. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. * - * @return true if the read succeeded, false if not. The read can fail - * because of an unsupported pixel config. + * @return true if the read succeeded, false if not. The read can fail because of an unsupported + * pixel config. */ bool readTexturePixels(GrTexture* texture, int left, int top, int width, int height, GrPixelConfig config, void* buffer, - size_t rowBytes) { - return this->internalReadTexturePixels(texture, left, top, - width, height, - config, buffer, rowBytes, 0); - } + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); /** * Writes a rectangle of pixels to a texture. @@ -549,14 +553,15 @@ public: * @param buffer memory to read pixels from * @param rowBytes number of bytes bewtween consecutive rows. Zero * means rows are tightly packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. */ void writeTexturePixels(GrTexture* texture, int left, int top, int width, int height, GrPixelConfig config, const void* buffer, - size_t rowBytes) { - this->internalWriteTexturePixels(texture, left, top, width, height, - config, buffer, rowBytes, 0); - } + size_t rowBytes, + uint32_t pixelOpsFlags = 0); + + /** * Copies all texels from one texture to another. * @param src the texture to copy from. @@ -785,49 +790,12 @@ private: void internalDrawPath(const GrPaint& paint, const SkPath& path, GrPathFill fill, const GrPoint* translate); - /** - * Flags to the internal read/write pixels funcs - */ - enum PixelOpsFlags { - kDontFlush_PixelOpsFlag = 0x1, - }; - GrTexture* createResizedTexture(const GrTextureDesc& desc, const GrCacheData& cacheData, void* srcData, size_t rowBytes, bool needsFiltering); - bool internalReadRenderTargetPixels(GrRenderTarget* target, - int left, int top, - int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes, uint32_t flags); - - void internalWriteRenderTargetPixels(GrRenderTarget* target, - int left, int top, - int width, int height, - GrPixelConfig, const void* buffer, - size_t rowBytes, uint32_t flags); - - bool internalReadTexturePixels(GrTexture* texture, - int left, int top, - int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes, uint32_t flags); - - void internalWriteTexturePixels(GrTexture* texture, - int left, int top, - int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes, uint32_t flags); - // needed for access to internalWriteTexturePixels. TODO: make GrContext - // be a facade for an internal class. Then functions that are public on the - // internal class would have only be callable in src/gpu. The facade would - // only have to functions necessary for clients. - friend class GrAtlas; - friend class GrTextureStripAtlas; - // Needed so GrTexture's returnToCache helper function can call // addExistingTextureToCache friend class GrTexture; diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h index d69e5cada9..33df8c6329 100644 --- a/include/gpu/GrRenderTarget.h +++ b/include/gpu/GrRenderTarget.h @@ -53,39 +53,17 @@ public: return this; } - /** - * Reads a rectangle of pixels from the render target. - * @param left left edge of the rectangle to read (inclusive) - * @param top top edge of the rectangle to read (inclusive) - * @param width width of rectangle to read in pixels. - * @param height height of rectangle to read in pixels. - * @param config the pixel config of the destination buffer - * @param buffer memory to read the rectangle into. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. - * - * @return true if the read succeeded, false if not. The read can fail - * because of an unsupported pixel config. - */ virtual bool readPixels(int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes) SK_OVERRIDE; + GrPixelConfig config, + void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0) SK_OVERRIDE; - /** - * Copy the src pixels [buffer, rowbytes, pixelconfig] into the render - * target at the specified rectangle. - * @param left left edge of the rectangle to write (inclusive) - * @param top top edge of the rectangle to write (inclusive) - * @param width width of rectangle to write in pixels. - * @param height height of rectangle to write in pixels. - * @param config the pixel config of the source buffer - * @param buffer memory to read the rectangle from. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. - */ virtual void writePixels(int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes) SK_OVERRIDE; + GrPixelConfig config, + const void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0) SK_OVERRIDE; // GrRenderTarget /** diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h index dcd5b66283..f87b9b4e10 100644 --- a/include/gpu/GrSamplerState.h +++ b/include/gpu/GrSamplerState.h @@ -130,6 +130,7 @@ public: const GrMatrix& getMatrix() const { return fMatrix; } bool swapsRAndB() const { return fSwapRAndB; } + bool premultiply() const { return fPremultiply; } GrTextureParams* textureParams() { return &fTextureParams; } const GrTextureParams& getTextureParams() const { return fTextureParams; } @@ -146,6 +147,12 @@ public: void setRAndBSwap(bool swap) { fSwapRAndB = swap; } /** + * If the texture is RGBA/BGRA 8888 config then its rgb components will be + * multiplied by its a component after the texture read. + **/ + void setPremultiply(bool premul) { fPremultiply = premul; } + + /** * Multiplies the current sampler matrix a matrix * * After this call M' = M*m where M is the old matrix, m is the parameter @@ -163,6 +170,7 @@ public: fTextureParams.reset(tileXAndY, filter); fMatrix = matrix; fSwapRAndB = false; + fPremultiply = false; GrSafeSetNull(fCustomStage); } void reset(SkShader::TileMode wrapXAndY, bool filter) { @@ -184,6 +192,7 @@ public: private: GrTextureParams fTextureParams; bool fSwapRAndB; + bool fPremultiply; // temporary, will be replaced soon by a custom stage. GrMatrix fMatrix; GrCustomStage* fCustomStage; diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index 2d39b5e10b..aa237aee4d 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -66,34 +66,40 @@ public: * @param height height of rectangle to read in pixels. * @param config the pixel config of the destination buffer * @param buffer memory to read the rectangle into. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum. * - * @return true if the read succeeded, false if not. The read can fail - * because of an unsupported pixel config. + * @return true if the read succeeded, false if not. The read can fail because of an unsupported + * pixel config. */ virtual bool readPixels(int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes) = 0; + GrPixelConfig config, + void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0) = 0; /** - * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface - * at the specified rectangle. + * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified + * rectangle. * @param left left edge of the rectangle to write (inclusive) * @param top top edge of the rectangle to write (inclusive) * @param width width of rectangle to write in pixels. * @param height height of rectangle to write in pixels. * @param config the pixel config of the source buffer * @param buffer memory to read the rectangle from. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum. */ virtual void writePixels(int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes) = 0; + GrPixelConfig config, + const void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0) = 0; protected: - GrTextureDesc fDesc; + GrTextureDesc fDesc; GrSurface(GrGpu* gpu, const GrTextureDesc& desc) : INHERITED(gpu) diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h index a1b7eabd85..c7bfb8c363 100644 --- a/include/gpu/GrTexture.h +++ b/include/gpu/GrTexture.h @@ -55,39 +55,18 @@ public: GrBytesPerPixel(fDesc.fConfig); } - // from GrSurface - /** - * Read a rectangle of pixels from the texture. - * @param left left edge of the rectangle to read (inclusive) - * @param top top edge of the rectangle to read (inclusive) - * @param width width of rectangle to read in pixels. - * @param height height of rectangle to read in pixels. - * @param config the pixel config of the destination buffer - * @param buffer memory to read the rectangle into. - * @param rowBytes number of bytes bewtween consecutive rows. Zero - * means rows are tightly packed. - * - * @return true if the read succeeded, false if not. The read can fail - * because of a unsupported pixel config. - */ + // GrSurface overrides virtual bool readPixels(int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes) SK_OVERRIDE; + GrPixelConfig config, + void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0) SK_OVERRIDE; - /** - * Writes a rectangle of pixels to the texture. - * @param left left edge of the rectangle to write (inclusive) - * @param top top edge of the rectangle to write (inclusive) - * @param width width of rectangle to write in pixels. - * @param height height of rectangle to write in pixels. - * @param config the pixel config of the source buffer - * @param buffer memory to read pixels from - * @param rowBytes number of bytes between consecutive rows. Zero - * means rows are tightly packed. - */ virtual void writePixels(int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes) SK_OVERRIDE; + GrPixelConfig config, + const void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0) SK_OVERRIDE; /** * @return this texture diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 9fbdb741ab..58f8968530 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -276,13 +276,6 @@ static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) { /** * Pixel configurations. - * - * Unpremultiplied configs are intended for converting pixel data in and out - * from skia. Surfaces with these configs have limited support. As an input - * (GrPaint texture) the corresponding GrSamplerState must have its filter set - * to kNearest_Filter. Otherwise, the draw will fail. When the render target - * has an unpremultiplied config draws must use blend coeffs 1,0 (AKA src-mode). - * Other coeffs will cause the draw to fail. */ enum GrPixelConfig { kUnknown_GrPixelConfig, @@ -294,47 +287,39 @@ enum GrPixelConfig { */ kRGBA_4444_GrPixelConfig, /** - * Premultiplied. Byte order is r,g,b,a - */ - kRGBA_8888_PM_GrPixelConfig, - /** - * Unpremultiplied. Byte order is r,g,b,a - */ - kRGBA_8888_UPM_GrPixelConfig, - /** - * Premultiplied. Byte order is b,g,r,a + * Premultiplied. Byte order is r,g,b,a. */ - kBGRA_8888_PM_GrPixelConfig, + kRGBA_8888_GrPixelConfig, /** - * Unpremultiplied. Byte order is b,g,r,a + * Premultiplied. Byte order is b,g,r,a. */ - kBGRA_8888_UPM_GrPixelConfig, + kBGRA_8888_GrPixelConfig, kGrPixelConfigCount }; -// Aliases for pixel configs that match skia's byte order +// Aliases for pixel configs that match skia's byte order. #ifndef SK_CPU_LENDIAN #error "Skia gpu currently assumes little endian" #endif #if 24 == SK_A32_SHIFT && 16 == SK_R32_SHIFT && \ 8 == SK_G32_SHIFT && 0 == SK_B32_SHIFT - static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kBGRA_8888_PM_GrPixelConfig; - static const GrPixelConfig kSkia8888_UPM_GrPixelConfig = kBGRA_8888_UPM_GrPixelConfig; + static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig; #elif 24 == SK_A32_SHIFT && 16 == SK_B32_SHIFT && \ 8 == SK_G32_SHIFT && 0 == SK_R32_SHIFT - static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kRGBA_8888_PM_GrPixelConfig; - static const GrPixelConfig kSkia8888_UPM_GrPixelConfig = kRGBA_8888_UPM_GrPixelConfig; + static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig; #else #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format." #endif +// This alias is deprecated and will be removed. +static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kSkia8888_GrPixelConfig; + // Returns true if the pixel config has 8bit r,g,b,a components in that byte // order static inline bool GrPixelConfigIsRGBA8888(GrPixelConfig config) { switch (config) { - case kRGBA_8888_PM_GrPixelConfig: - case kRGBA_8888_UPM_GrPixelConfig: + case kRGBA_8888_GrPixelConfig: return true; default: return false; @@ -345,8 +330,7 @@ static inline bool GrPixelConfigIsRGBA8888(GrPixelConfig config) { // order static inline bool GrPixelConfigIsBGRA8888(GrPixelConfig config) { switch (config) { - case kBGRA_8888_PM_GrPixelConfig: - case kBGRA_8888_UPM_GrPixelConfig: + case kBGRA_8888_GrPixelConfig: return true; default: return false; @@ -356,10 +340,8 @@ static inline bool GrPixelConfigIsBGRA8888(GrPixelConfig config) { // Returns true if the pixel config is 32 bits per pixel static inline bool GrPixelConfigIs32Bit(GrPixelConfig config) { switch (config) { - case kRGBA_8888_PM_GrPixelConfig: - case kRGBA_8888_UPM_GrPixelConfig: - case kBGRA_8888_PM_GrPixelConfig: - case kBGRA_8888_UPM_GrPixelConfig: + case kRGBA_8888_GrPixelConfig: + case kBGRA_8888_GrPixelConfig: return true; default: return false; @@ -370,14 +352,10 @@ static inline bool GrPixelConfigIs32Bit(GrPixelConfig config) { // swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) { switch (config) { - case kBGRA_8888_PM_GrPixelConfig: - return kRGBA_8888_PM_GrPixelConfig; - case kBGRA_8888_UPM_GrPixelConfig: - return kRGBA_8888_UPM_GrPixelConfig; - case kRGBA_8888_PM_GrPixelConfig: - return kBGRA_8888_PM_GrPixelConfig; - case kRGBA_8888_UPM_GrPixelConfig: - return kBGRA_8888_UPM_GrPixelConfig; + case kBGRA_8888_GrPixelConfig: + return kRGBA_8888_GrPixelConfig; + case kRGBA_8888_GrPixelConfig: + return kBGRA_8888_GrPixelConfig; default: return kUnknown_GrPixelConfig; } @@ -391,10 +369,8 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) { case kRGB_565_GrPixelConfig: case kRGBA_4444_GrPixelConfig: return 2; - case kRGBA_8888_PM_GrPixelConfig: - case kRGBA_8888_UPM_GrPixelConfig: - case kBGRA_8888_PM_GrPixelConfig: - case kBGRA_8888_UPM_GrPixelConfig: + case kRGBA_8888_GrPixelConfig: + case kBGRA_8888_GrPixelConfig: return 4; default: return 0; @@ -410,20 +386,6 @@ static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) { } } -/** - * Premultiplied alpha is the usual for skia. Therefore, configs that are - * ambiguous (alpha-only or color-only) are considered premultiplied. - */ -static inline bool GrPixelConfigIsUnpremultiplied(GrPixelConfig config) { - switch (config) { - case kRGBA_8888_UPM_GrPixelConfig: - case kBGRA_8888_UPM_GrPixelConfig: - return true; - default: - return false; - } -} - static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) { switch (config) { case kAlpha_8_GrPixelConfig: diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp index 2b76d13048..491f6cff83 100644 --- a/src/gpu/GrAtlas.cpp +++ b/src/gpu/GrAtlas.cpp @@ -111,13 +111,13 @@ bool GrAtlas::addSubImage(int width, int height, const void* image, } adjustForPlot(loc, fPlot); GrContext* context = fTexture->getContext(); - // We call the internal version so that we don't force a flush. We assume - // our caller is smart and hasn't referenced the part of the texture we're - // about to update since the last flush. - context->internalWriteTexturePixels(fTexture, loc->fX, loc->fY, - dstW, dstH, fTexture->config(), - image, 0, - GrContext::kDontFlush_PixelOpsFlag); + // We pass the flag that does not force a flush. We assume our caller is + // smart and hasn't referenced the part of the texture we're about to update + // since the last flush. + context->writeTexturePixels(fTexture, + loc->fX, loc->fY, dstW, dstH, + fTexture->config(), image, 0, + GrContext::kDontFlush_PixelOpsFlag); // now tell the caller to skip the top/left BORDER loc->fX += BORDER; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 89537adc45..49d220f537 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1185,46 +1185,39 @@ void GrContext::flushDrawBuffer() { } } -void GrContext::internalWriteTexturePixels(GrTexture* texture, - int left, int top, - int width, int height, - GrPixelConfig config, - const void* buffer, - size_t rowBytes, - uint32_t flags) { +void GrContext::writeTexturePixels(GrTexture* texture, + int left, int top, int width, int height, + GrPixelConfig config, const void* buffer, size_t rowBytes, + uint32_t flags) { SK_TRACE_EVENT0("GrContext::writeTexturePixels"); ASSERT_OWNED_RESOURCE(texture); - if (!(kDontFlush_PixelOpsFlag & flags)) { - this->flush(); - } // TODO: use scratch texture to perform conversion - if (GrPixelConfigIsUnpremultiplied(texture->config()) != - GrPixelConfigIsUnpremultiplied(config)) { + if (kUnpremul_PixelOpsFlag & flags) { return; } + if (!(kDontFlush_PixelOpsFlag & flags)) { + this->flush(); + } fGpu->writeTexturePixels(texture, left, top, width, height, config, buffer, rowBytes); } -bool GrContext::internalReadTexturePixels(GrTexture* texture, - int left, int top, - int width, int height, - GrPixelConfig config, - void* buffer, - size_t rowBytes, - uint32_t flags) { +bool GrContext::readTexturePixels(GrTexture* texture, + int left, int top, int width, int height, + GrPixelConfig config, void* buffer, size_t rowBytes, + uint32_t flags) { SK_TRACE_EVENT0("GrContext::readTexturePixels"); ASSERT_OWNED_RESOURCE(texture); // TODO: code read pixels for textures that aren't also rendertargets GrRenderTarget* target = texture->asRenderTarget(); if (NULL != target) { - return this->internalReadRenderTargetPixels(target, - left, top, width, height, - config, buffer, rowBytes, - flags); + return this->readRenderTargetPixels(target, + left, top, width, height, + config, buffer, rowBytes, + flags); } else { return false; } @@ -1239,19 +1232,22 @@ namespace { * if the GrPixelConfig has no equivalent Config8888. */ bool grconfig_to_config8888(GrPixelConfig config, + bool unpremul, SkCanvas::Config8888* config8888) { switch (config) { - case kRGBA_8888_PM_GrPixelConfig: - *config8888 = SkCanvas::kRGBA_Premul_Config8888; - return true; - case kRGBA_8888_UPM_GrPixelConfig: - *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; - return true; - case kBGRA_8888_PM_GrPixelConfig: - *config8888 = SkCanvas::kBGRA_Premul_Config8888; + case kRGBA_8888_GrPixelConfig: + if (unpremul) { + *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; + } else { + *config8888 = SkCanvas::kRGBA_Premul_Config8888; + } return true; - case kBGRA_8888_UPM_GrPixelConfig: - *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; + case kBGRA_8888_GrPixelConfig: + if (unpremul) { + *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; + } else { + *config8888 = SkCanvas::kBGRA_Premul_Config8888; + } return true; default: return false; @@ -1259,13 +1255,10 @@ bool grconfig_to_config8888(GrPixelConfig config, } } -bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, - int left, int top, - int width, int height, - GrPixelConfig config, - void* buffer, - size_t rowBytes, - uint32_t flags) { +bool GrContext::readRenderTargetPixels(GrRenderTarget* target, + int left, int top, int width, int height, + GrPixelConfig config, void* buffer, size_t rowBytes, + uint32_t flags) { SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); ASSERT_OWNED_RESOURCE(target); @@ -1280,21 +1273,21 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, this->flush(); } - if (!GrPixelConfigIsUnpremultiplied(target->config()) && - GrPixelConfigIsUnpremultiplied(config) && + if ((kUnpremul_PixelOpsFlag & flags) && !fGpu->canPreserveReadWriteUnpremulPixels()) { + SkCanvas::Config8888 srcConfig8888, dstConfig8888; - if (!grconfig_to_config8888(target->config(), &srcConfig8888) || - !grconfig_to_config8888(config, &dstConfig8888)) { + if (!grconfig_to_config8888(target->config(), false, &srcConfig8888) || + !grconfig_to_config8888(config, true, &dstConfig8888)) { return false; } // do read back using target's own config - this->internalReadRenderTargetPixels(target, - left, top, - width, height, - target->config(), - buffer, rowBytes, - kDontFlush_PixelOpsFlag); + this->readRenderTargetPixels(target, + left, top, + width, height, + target->config(), + buffer, rowBytes, + kDontFlush_PixelOpsFlag); // we already flushed // sw convert the pixels to unpremul config uint32_t* pixels = reinterpret_cast<uint32_t*>(buffer); SkConvertConfig8888Pixels(pixels, rowBytes, dstConfig8888, @@ -1312,10 +1305,9 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, fGpu->readPixelsWillPayForYFlip(target, left, top, width, height, config, rowBytes); - bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && - GrPixelConfigIsUnpremultiplied(config)); + bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); - if (NULL == src && alphaConversion) { + if (NULL == src && unpremul) { // we should fallback to cpu conversion here. This could happen when // we were given an external render target by the client that is not // also a texture (e.g. FBO 0 in GL) @@ -1323,7 +1315,7 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, } // we draw to a scratch texture if any of these conversion are applied GrAutoScratchTexture ast; - if (flipY || swapRAndB || alphaConversion) { + if (flipY || swapRAndB || unpremul) { GrAssert(NULL != src); if (swapRAndB) { config = GrPixelConfigSwapRAndB(config); @@ -1363,6 +1355,10 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, GrDrawState* drawState = fGpu->drawState(); drawState->setRenderTarget(target); + if (unpremul) { + drawState->enableState(GrDrawState::kUnpremultiply_StageBit); + } + GrMatrix matrix; if (flipY) { matrix.setTranslate(SK_Scalar1 * left, @@ -1421,13 +1417,12 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { fGpu->drawSimpleRect(rect, NULL); } -void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, - int left, int top, - int width, int height, - GrPixelConfig config, - const void* buffer, - size_t rowBytes, - uint32_t flags) { +void GrContext::writeRenderTargetPixels(GrRenderTarget* target, + int left, int top, int width, int height, + GrPixelConfig config, + const void* buffer, + size_t rowBytes, + uint32_t flags) { SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); ASSERT_OWNED_RESOURCE(target); @@ -1441,30 +1436,26 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, // TODO: when underlying api has a direct way to do this we should use it // (e.g. glDrawPixels on desktop GL). - // If the RT is also a texture and we don't have to do PM/UPM conversion - // then take the texture path, which we expect to be at least as fast or - // faster since it doesn't use an intermediate texture as we do below. + // If the RT is also a texture and we don't have to premultiply then take the texture path. + // We expect to be at least as fast or faster since it doesn't use an intermediate texture as + // we do below. #if !GR_MAC_BUILD // At least some drivers on the Mac get confused when glTexImage2D is called // on a texture attached to an FBO. The FBO still sees the old image. TODO: // determine what OS versions and/or HW is affected. - if (NULL != target->asTexture() && - GrPixelConfigIsUnpremultiplied(target->config()) == - GrPixelConfigIsUnpremultiplied(config)) { - - this->internalWriteTexturePixels(target->asTexture(), - left, top, width, height, - config, buffer, rowBytes, flags); + if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags)) { + this->writeTexturePixels(target->asTexture(), + left, top, width, height, + config, buffer, rowBytes, flags); return; } #endif - if (!GrPixelConfigIsUnpremultiplied(target->config()) && - GrPixelConfigIsUnpremultiplied(config) && + if ((kUnpremul_PixelOpsFlag & flags) && !fGpu->canPreserveReadWriteUnpremulPixels()) { SkCanvas::Config8888 srcConfig8888, dstConfig8888; - if (!grconfig_to_config8888(config, &srcConfig8888) || - !grconfig_to_config8888(target->config(), &dstConfig8888)) { + if (!grconfig_to_config8888(config, true, &srcConfig8888) || + !grconfig_to_config8888(target->config(), false, &dstConfig8888)) { return; } // allocate a tmp buffer and sw convert the pixels to premul @@ -1474,11 +1465,13 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, src, rowBytes, srcConfig8888, width, height); // upload the already premul pixels - this->internalWriteRenderTargetPixels(target, - left, top, - width, height, - target->config(), - tmpPixels, 4 * width, flags); + flags &= ~kUnpremul_PixelOpsFlag; + this->writeRenderTargetPixels(target, + left, top, + width, height, + target->config(), + tmpPixels, 4 * width, + flags); return; } @@ -1498,8 +1491,8 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, if (NULL == texture) { return; } - this->internalWriteTexturePixels(texture, 0, 0, width, height, - config, buffer, rowBytes, flags); + this->writeTexturePixels(texture, 0, 0, width, height, + config, buffer, rowBytes, flags & ~kUnpremul_PixelOpsFlag); GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); GrDrawState* drawState = fGpu->drawState(); @@ -1513,6 +1506,7 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, drawState->sampler(0)->reset(matrix); drawState->createTextureEffect(0, texture); drawState->sampler(0)->setRAndBSwap(swapRAndB); + drawState->sampler(0)->setPremultiply(SkToBool(kUnpremul_PixelOpsFlag & flags)); static const GrVertexLayout layout = 0; static const int VCOUNT = 4; @@ -1755,8 +1749,8 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, AutoClip acs(this, srcRect); - GrAssert(kBGRA_8888_PM_GrPixelConfig == srcTexture->config() || - kRGBA_8888_PM_GrPixelConfig == srcTexture->config() || + GrAssert(kBGRA_8888_GrPixelConfig == srcTexture->config() || + kRGBA_8888_GrPixelConfig == srcTexture->config() || kAlpha_8_GrPixelConfig == srcTexture->config()); GrTextureDesc desc; @@ -1875,7 +1869,7 @@ GrTexture* GrContext::applyMorphology(GrTexture* srcTexture, desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; desc.fWidth = SkScalarCeilToInt(rect.width()); desc.fHeight = SkScalarCeilToInt(rect.height()); - desc.fConfig = kRGBA_8888_PM_GrPixelConfig; + desc.fConfig = kRGBA_8888_GrPixelConfig; if (radius.fWidth > 0) { GrAutoScratchTexture ast(this, desc); this->setRenderTarget(ast.texture()->asRenderTarget()); diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 0d81019ebb..cc68aede70 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -668,7 +668,14 @@ public: * Draws will apply the color matrix, otherwise the color matrix is * ignored. */ - kColorMatrix_StateBit = 0x20, + kColorMatrix_StateBit = 0x10, + + /** + * The pixels written to the render target should be unpremultiplied. + * This flag is temporary and will be removed when this functionality is + * captured in a custom stage. + */ + kUnpremultiply_StageBit = 0x20, // Users of the class may add additional bits to the vector kDummyStateBit, diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index f0f1864a55..5b90480cba 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -760,29 +760,6 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, if (NULL == drawState.getRenderTarget()) { return false; } - if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) { - if (kOne_GrBlendCoeff != drawState.getSrcBlendCoeff() || - kZero_GrBlendCoeff != drawState.getDstBlendCoeff()) { - return false; - } - } - // We don't support using unpremultiplied textures with bilerp. Alpha-multiplication is not - // distributive with respect to filtering. We'd have to alpha-mul each texel before filtering. - // Until Skia itself supports unpremultiplied configs there is no pressure to implement this. - for (int s = 0; s < GrDrawState::kNumStages; ++s) { - if (drawState.isStageEnabled(s)) { - const GrCustomStage* stage = drawState.getSampler(s).getCustomStage(); - int numTextures = stage->numTextures(); - for (int t = 0; t < numTextures; ++t) { - GrTexture* texture = stage->texture(t); - GrAssert(NULL != texture); - if (GrPixelConfigIsUnpremultiplied(texture->config()) && - drawState.getSampler(s).getTextureParams().isBilerp()) { - return false; - } - } - } - } return true; } diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index c159f5e735..923f711cc7 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -263,8 +263,6 @@ bool GrGpu::readPixels(GrRenderTarget* target, int left, int top, int width, int height, GrPixelConfig config, void* buffer, size_t rowBytes, bool invertY) { - GrAssert(GrPixelConfigIsUnpremultiplied(config) == - GrPixelConfigIsUnpremultiplied(target->config())); this->handleDirtyContext(); return this->onReadPixels(target, left, top, width, height, config, buffer, rowBytes, invertY); @@ -274,8 +272,6 @@ void GrGpu::writeTexturePixels(GrTexture* texture, int left, int top, int width, int height, GrPixelConfig config, const void* buffer, size_t rowBytes) { - GrAssert(GrPixelConfigIsUnpremultiplied(config) == - GrPixelConfigIsUnpremultiplied(texture->config())); this->handleDirtyContext(); this->onWriteTexturePixels(texture, left, top, width, height, config, buffer, rowBytes); diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp index 071c885caf..816a633d77 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -16,31 +16,35 @@ SK_DEFINE_INST_COUNT(GrRenderTarget) bool GrRenderTarget::readPixels(int left, int top, int width, int height, - GrPixelConfig config, void* buffer, - size_t rowBytes) { + GrPixelConfig config, + void* buffer, + size_t rowBytes, + uint32_t pixelOpsFlags) { // go through context so that all necessary flushing occurs GrContext* context = this->getContext(); if (NULL == context) { return false; } return context->readRenderTargetPixels(this, - left, top, - width, height, - config, buffer, rowBytes); + left, top, width, height, + config, buffer, rowBytes, + pixelOpsFlags); } void GrRenderTarget::writePixels(int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t rowBytes) { + GrPixelConfig config, + const void* buffer, + size_t rowBytes, + uint32_t pixelOpsFlags) { // go through context so that all necessary flushing occurs GrContext* context = this->getContext(); if (NULL == context) { return; } context->writeRenderTargetPixels(this, - left, top, - width, height, - config, buffer, rowBytes); + left, top, width, height, + config, buffer, rowBytes, + pixelOpsFlags); } void GrRenderTarget::resolve() { diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index d2e27367df..182c90e5d2 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -41,30 +41,30 @@ void GrTexture::internal_dispose() const { bool GrTexture::readPixels(int left, int top, int width, int height, GrPixelConfig config, void* buffer, - size_t rowBytes) { + size_t rowBytes, uint32_t pixelOpsFlags) { // go through context so that all necessary flushing occurs GrContext* context = this->getContext(); if (NULL == context) { return false; } return context->readTexturePixels(this, - left, top, - width, height, - config, buffer, rowBytes); + left, top, width, height, + config, buffer, rowBytes, + pixelOpsFlags); } void GrTexture::writePixels(int left, int top, int width, int height, GrPixelConfig config, const void* buffer, - size_t rowBytes) { + size_t rowBytes, uint32_t pixelOpsFlags) { // go through context so that all necessary flushing occurs GrContext* context = this->getContext(); if (NULL == context) { return; } context->writeTexturePixels(this, - left, top, - width, height, - config, buffer, rowBytes); + left, top, width, height, + config, buffer, rowBytes, + pixelOpsFlags); } void GrTexture::releaseRenderTarget() { diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 14e4ff9672..1eb9e49ee4 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -291,20 +291,26 @@ void SkGpuDevice::makeRenderTargetCurrent() { /////////////////////////////////////////////////////////////////////////////// namespace { -GrPixelConfig config8888_to_gr_config(SkCanvas::Config8888 config8888) { +GrPixelConfig config8888_to_grconfig_and_flags(SkCanvas::Config8888 config8888, uint32_t* flags) { switch (config8888) { case SkCanvas::kNative_Premul_Config8888: - return kSkia8888_PM_GrPixelConfig; + *flags = 0; + return kSkia8888_GrPixelConfig; case SkCanvas::kNative_Unpremul_Config8888: - return kSkia8888_UPM_GrPixelConfig; + *flags = GrContext::kUnpremul_PixelOpsFlag; + return kSkia8888_PM_GrPixelConfig; case SkCanvas::kBGRA_Premul_Config8888: - return kBGRA_8888_PM_GrPixelConfig; + *flags = 0; + return kBGRA_8888_GrPixelConfig; case SkCanvas::kBGRA_Unpremul_Config8888: - return kBGRA_8888_UPM_GrPixelConfig; + *flags = GrContext::kUnpremul_PixelOpsFlag; + return kBGRA_8888_GrPixelConfig; case SkCanvas::kRGBA_Premul_Config8888: - return kRGBA_8888_PM_GrPixelConfig; + *flags = 0; + return kRGBA_8888_GrPixelConfig; case SkCanvas::kRGBA_Unpremul_Config8888: - return kRGBA_8888_UPM_GrPixelConfig; + *flags = GrContext::kUnpremul_PixelOpsFlag; + return kRGBA_8888_GrPixelConfig; default: GrCrash("Unexpected Config8888."); return kSkia8888_PM_GrPixelConfig; @@ -322,14 +328,16 @@ bool SkGpuDevice::onReadPixels(const SkBitmap& bitmap, SkAutoLockPixels alp(bitmap); GrPixelConfig config; - config = config8888_to_gr_config(config8888); + uint32_t flags; + config = config8888_to_grconfig_and_flags(config8888, &flags); return fContext->readRenderTargetPixels(fRenderTarget, x, y, bitmap.width(), bitmap.height(), config, bitmap.getPixels(), - bitmap.rowBytes()); + bitmap.rowBytes(), + flags); } void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y, @@ -340,14 +348,16 @@ void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y, } GrPixelConfig config; + uint32_t flags; if (SkBitmap::kARGB_8888_Config == bitmap.config()) { - config = config8888_to_gr_config(config8888); + config = config8888_to_grconfig_and_flags(config8888, &flags); } else { + flags = 0; config= SkBitmapConfig2GrPixelConfig(bitmap.config()); } fRenderTarget->writePixels(x, y, bitmap.width(), bitmap.height(), - config, bitmap.getPixels(), bitmap.rowBytes()); + config, bitmap.getPixels(), bitmap.rowBytes(), flags); } namespace { @@ -874,7 +884,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, desc.fHeight = SkScalarCeilToInt(srcRect.height()); // We actually only need A8, but it often isn't supported as a // render target so default to RGBA_8888 - desc.fConfig = kRGBA_8888_PM_GrPixelConfig; + desc.fConfig = kRGBA_8888_GrPixelConfig; if (context->isConfigRenderable(kAlpha_8_GrPixelConfig)) { desc.fConfig = kAlpha_8_GrPixelConfig; @@ -1527,7 +1537,7 @@ static GrTexture* filter_texture(GrContext* context, GrTexture* texture, desc.fFlags = kRenderTarget_GrTextureFlagBit, desc.fWidth = SkScalarCeilToInt(rect.width()); desc.fHeight = SkScalarCeilToInt(rect.height()); - desc.fConfig = kRGBA_8888_PM_GrPixelConfig; + desc.fConfig = kRGBA_8888_GrPixelConfig; GrCustomStage* stage; if (filter->canFilterImageGPU()) { diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index a98b8fd75a..2052b77b39 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -100,7 +100,7 @@ static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, GrContext::kExact_ScratchTexMatch); result->writePixels(0, 0, bitmap->width(), bitmap->height(), desc.fConfig, - storage.get(), 0); + storage.get()); return result; } diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index f31d7d72a6..3462e9243b 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -137,13 +137,13 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) { // Pass in the kDontFlush flag, since we know we're writing to a part of this texture // that is not currently in use - fDesc.fContext->internalWriteTexturePixels(fTexture, 0, - rowNumber * fDesc.fRowHeight, - fDesc.fWidth, - fDesc.fRowHeight, - SkBitmapConfig2GrPixelConfig(data.config()), - data.getPixels(), data.rowBytes(), - GrContext::kDontFlush_PixelOpsFlag); + fDesc.fContext->writeTexturePixels(fTexture, + 0, rowNumber * fDesc.fRowHeight, + fDesc.fWidth, fDesc.fRowHeight, + SkBitmapConfig2GrPixelConfig(data.config()), + data.getPixels(), + data.rowBytes(), + GrContext::kDontFlush_PixelOpsFlag); } GrAssert(rowNumber >= 0); diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 0afbe57319..2682eb2680 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -109,7 +109,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo) { fBGRAIsInternalFormat = true; } GrAssert(fBGRAFormatSupport || - kSkia8888_PM_GrPixelConfig != kBGRA_8888_PM_GrPixelConfig); + kSkia8888_GrPixelConfig != kBGRA_8888_GrPixelConfig); } if (kDesktop_GrGLBinding == binding) { diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 8089d100c2..03462e743b 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -335,18 +335,12 @@ void GrGpuGL::fillInConfigRenderableTable() { fConfigRenderSupport[kRGBA_4444_GrPixelConfig] = true; if (this->glCaps().rgba8RenderbufferSupport()) { - fConfigRenderSupport[kRGBA_8888_PM_GrPixelConfig] = true; + fConfigRenderSupport[kRGBA_8888_GrPixelConfig] = true; } if (this->glCaps().bgraFormatSupport()) { - fConfigRenderSupport[kBGRA_8888_PM_GrPixelConfig] = true; + fConfigRenderSupport[kBGRA_8888_GrPixelConfig] = true; } - - // the un-premultiplied formats just inherit the premultiplied setting - fConfigRenderSupport[kRGBA_8888_UPM_GrPixelConfig] = - fConfigRenderSupport[kRGBA_8888_PM_GrPixelConfig]; - fConfigRenderSupport[kBGRA_8888_UPM_GrPixelConfig] = - fConfigRenderSupport[kBGRA_8888_PM_GrPixelConfig]; } bool GrGpuGL::canPreserveReadWriteUnpremulPixels() { @@ -375,7 +369,7 @@ bool GrGpuGL::canPreserveReadWriteUnpremulPixels() { kNoStencil_GrTextureFlagBit; dstDesc.fWidth = 256; dstDesc.fHeight = 256; - dstDesc.fConfig = kRGBA_8888_PM_GrPixelConfig; + dstDesc.fConfig = kRGBA_8888_GrPixelConfig; SkAutoTUnref<GrTexture> dstTex(this->createTexture(dstDesc, NULL, 0)); if (!dstTex.get()) { @@ -397,16 +391,20 @@ bool GrGpuGL::canPreserveReadWriteUnpremulPixels() { fUnpremulConversion = gMethods[i]; rt->writePixels(0, 0, 256, 256, - kRGBA_8888_UPM_GrPixelConfig, srcData, 0); + kRGBA_8888_GrPixelConfig, srcData, 0, + GrContext::kUnpremul_PixelOpsFlag); rt->readPixels(0, 0, 256, 256, - kRGBA_8888_UPM_GrPixelConfig, firstRead, 0); + kRGBA_8888_GrPixelConfig, firstRead, 0, + GrContext::kUnpremul_PixelOpsFlag); rt->writePixels(0, 0, 256, 256, - kRGBA_8888_UPM_GrPixelConfig, firstRead, 0); + kRGBA_8888_GrPixelConfig, firstRead, 0, + GrContext::kUnpremul_PixelOpsFlag); rt->readPixels(0, 0, 256, 256, - kRGBA_8888_UPM_GrPixelConfig, secondRead, 0); + kRGBA_8888_GrPixelConfig, secondRead, 0, + GrContext::kUnpremul_PixelOpsFlag); failed = false; for (int j = 0; j < 256 * 256; ++j) { if (firstRead[j] != secondRead[j]) { @@ -1397,9 +1395,6 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) { static const GrGLfloat scale255 = 1.f / 255.f; a = GrColorUnpackA(color) * scale255; GrGLfloat scaleRGB = scale255; - if (GrPixelConfigIsUnpremultiplied(rt->config())) { - scaleRGB *= a; - } r = GrColorUnpackR(color) * scaleRGB; g = GrColorUnpackG(color) * scaleRGB; b = GrColorUnpackB(color) * scaleRGB; @@ -2321,8 +2316,7 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config, } switch (config) { - case kRGBA_8888_PM_GrPixelConfig: - case kRGBA_8888_UPM_GrPixelConfig: + case kRGBA_8888_GrPixelConfig: *internalFormat = GR_GL_RGBA; *externalFormat = GR_GL_RGBA; if (getSizedInternalFormat) { @@ -2332,8 +2326,7 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config, } *externalType = GR_GL_UNSIGNED_BYTE; break; - case kBGRA_8888_PM_GrPixelConfig: - case kBGRA_8888_UPM_GrPixelConfig: + case kBGRA_8888_GrPixelConfig: if (!this->glCaps().bgraFormatSupport()) { return false; } diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index c959f66b9a..c1eb36e9a7 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -733,7 +733,7 @@ void GrGpuGL::buildProgram(bool isPoints, stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag; } } - if (GrPixelConfigIsUnpremultiplied(texture->config())) { + if (sampler.premultiply()) { // Assert that if we're doing a premul conversion that the texture is 1 byte // per color component. The rounding performed by the shader generator (in // normalized float color space) assumes this. @@ -758,7 +758,7 @@ void GrGpuGL::buildProgram(bool isPoints, } } - if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) { + if (drawState.isStateFlagEnabled(GrDrawState::kUnpremultiply_StageBit)) { // The shader generator assumes that color channels are bytes // when rounding. GrAssert(4 == GrBytesPerPixel(drawState.getRenderTarget()->config())); diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp index a22ff5ae13..f2f1613d95 100644 --- a/tests/PremulAlphaRoundTripTest.cpp +++ b/tests/PremulAlphaRoundTripTest.cpp @@ -95,10 +95,11 @@ void PremulAlphaRoundTripTest(skiatest::Reporter* reporter, reinterpret_cast<uint32_t*>(readBmp1.getPixels()); uint32_t* pixels2 = reinterpret_cast<uint32_t*>(readBmp2.getPixels()); - for (int y = 0; y < 256; ++y) { - for (int x = 0; x < 256; ++x) { + bool success = true; + for (int y = 0; y < 256 && success; ++y) { + for (int x = 0; x < 256 && success; ++x) { int i = y * 256 + x; - REPORTER_ASSERT(reporter, pixels1[i] == pixels2[i]); + REPORTER_ASSERT(reporter, success = pixels1[i] == pixels2[i]); } } } |