Loading core/jni/android/graphics/Shader.cpp +10 −8 Original line number Diff line number Diff line #include "GraphicsJNI.h" #include "SkColorFilter.h" #include "SkGradientShader.h" #include "SkImagePriv.h" #include "SkShader.h" Loading Loading @@ -64,28 +65,29 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j jint tileModeX, jint tileModeY) { const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr); sk_sp<SkImage> image; sk_sp<SkColorFilter> colorFilter; if (jbitmap) { // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise, // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility. image = android::bitmap::toBitmap(env, jbitmap).makeImage(); image = android::bitmap::toBitmap(env, jbitmap).makeImage(&colorFilter); } if (!image.get()) { SkBitmap bitmap; image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode); } sk_sp<SkShader> baseShader = image->makeShader( sk_sp<SkShader> shader = image->makeShader( (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY); SkShader* shader; if (matrix) { shader = baseShader->makeWithLocalMatrix(*matrix).release(); } else { shader = baseShader.release(); shader = shader->makeWithLocalMatrix(*matrix); } if(colorFilter) { shader = shader->makeWithColorFilter(colorFilter); } ThrowIAE_IfNull(env, shader); return reinterpret_cast<jlong>(shader); ThrowIAE_IfNull(env, shader.get()); return reinterpret_cast<jlong>(shader.release()); } /////////////////////////////////////////////////////////////////////////////////////////////// Loading libs/hwui/GlopBuilder.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -296,6 +296,7 @@ void GlopBuilder::setFill(int color, float alphaScale, colorVector[2] = EOCF(srcColorMatrix[14] / 255.0f); colorVector[3] = srcColorMatrix[19] / 255.0f; // alpha is linear } else { ALOGE("unsupported ColorFilter type: %s", colorFilter->getTypeName()); LOG_ALWAYS_FATAL("unsupported ColorFilter"); } } else { Loading libs/hwui/SkiaCanvas.cpp +48 −13 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #include "pipeline/skia/AnimatedDrawables.h" #include <SkCanvasStateUtils.h> #include <SkColorFilter.h> // TODO remove me! #include <SkColorSpaceXformCanvas.h> #include <SkDrawable.h> #include <SkDeque.h> Loading Loading @@ -529,25 +531,49 @@ void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, cons // Canvas draw operations: Bitmaps // ---------------------------------------------------------------------------- inline static const SkPaint* addFilter(const SkPaint* origPaint, SkPaint* tmpPaint, sk_sp<SkColorFilter> colorFilter) { if (colorFilter) { if (origPaint) { *tmpPaint = *origPaint; } tmpPaint->setColorFilter(colorFilter); return tmpPaint; } else { return origPaint; } } void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) { mCanvas->drawImage(bitmap.makeImage(), left, top, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImage(image, left, top, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix, const SkPaint* paint) { void SkiaCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) { SkAutoCanvasRestore acr(mCanvas, true); mCanvas->concat(matrix); mCanvas->drawImage(hwuiBitmap.makeImage(), 0, 0, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImage(image, 0, 0, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop, void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom); SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); mCanvas->drawImageRect(hwuiBitmap.makeImage(), srcRect, dstRect, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImageRect(image, srcRect, dstRect, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeight, void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { const int ptCount = (meshWidth + 1) * (meshHeight + 1); const int indexCount = meshWidth * meshHeight * 6; Loading @@ -565,8 +591,8 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeigh // cons up texture coordinates and indices { const SkScalar w = SkIntToScalar(hwuiBitmap.width()); const SkScalar h = SkIntToScalar(hwuiBitmap.height()); const SkScalar w = SkIntToScalar(bitmap.width()); const SkScalar h = SkIntToScalar(bitmap.height()); const SkScalar dx = w / meshWidth; const SkScalar dy = h / meshHeight; Loading Loading @@ -627,17 +653,22 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeigh tmpPaint = *paint; } sk_sp<SkImage> image = hwuiBitmap.makeImage(); tmpPaint.setShader(image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)); sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); sk_sp<SkShader> shader = image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); if(colorFilter) { shader = shader->makeWithColorFilter(colorFilter); } tmpPaint.setShader(shader); mCanvas->drawVertices(builder.detach(), SkBlendMode::kModulate, tmpPaint); } void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk, void SkiaCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { SkCanvas::Lattice lattice; NinePatchUtils::SetLatticeDivs(&lattice, chunk, hwuiBitmap.width(), hwuiBitmap.height()); NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height()); lattice.fFlags = nullptr; int numFlags = 0; Loading @@ -654,7 +685,11 @@ void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk, lattice.fBounds = nullptr; SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); mCanvas->drawImageLattice(hwuiBitmap.makeImage().get(), lattice, dst, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImageLattice(image.get(), lattice, dst, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) { Loading libs/hwui/hwui/Bitmap.cpp +8 −11 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <ui/PixelFormat.h> #include <SkCanvas.h> #include <SkToSRGBColorFilter.h> #include <SkImagePriv.h> namespace android { Loading Loading @@ -208,11 +209,8 @@ Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info) buffer->incStrong(buffer); setImmutable(); // HW bitmaps are always immutable if (uirenderer::Properties::isSkiaEnabled()) { // GraphicBuffer should be in the display color space (Bitmap::createFrom is always // passing SRGB). The code that uploads into a GraphicBuffer should do color conversion if // needed. mImage = SkImage::MakeFromAHardwareBuffer(reinterpret_cast<AHardwareBuffer*>(buffer), mInfo.alphaType(), nullptr); mInfo.alphaType(), mInfo.refColorSpace()); } } Loading Loading @@ -319,7 +317,7 @@ GraphicBuffer* Bitmap::graphicBuffer() { return nullptr; } sk_sp<SkImage> Bitmap::makeImage() { sk_sp<SkImage> Bitmap::makeImage(sk_sp<SkColorFilter>* outputColorFilter) { sk_sp<SkImage> image = mImage; if (!image) { SkASSERT(!(isHardware() && uirenderer::Properties::isSkiaEnabled())); Loading @@ -330,12 +328,11 @@ sk_sp<SkImage> Bitmap::makeImage() { // Note we don't cache in this case, because the raster image holds a pointer to this Bitmap // internally and ~Bitmap won't be invoked. // TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here. if (uirenderer::Properties::isSkiaEnabled()) { image = SkMakeImageInColorSpace(skiaBitmap, SkColorSpace::MakeSRGB(), skiaBitmap.getGenerationID(), kNever_SkCopyPixelsMode); } else { image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode); } if(uirenderer::Properties::isSkiaEnabled() && image->colorSpace() != nullptr && !image->colorSpace()->isSRGB()) { *outputColorFilter = SkToSRGBColorFilter::Make(image->refColorSpace()); } return image; } Loading libs/hwui/hwui/Bitmap.h +13 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <SkBitmap.h> #include <SkColorFilter.h> #include <SkColorSpace.h> #include <SkImage.h> #include <SkImageInfo.h> Loading Loading @@ -96,9 +97,18 @@ public: GraphicBuffer* graphicBuffer(); // makeImage creates or returns a cached SkImage. Can be invoked from UI or render thread. // Caching is supported only for HW Bitmaps with skia pipeline. sk_sp<SkImage> makeImage(); /** * Creates or returns a cached SkImage and is safe to be invoked from either * the UI or RenderThread. * * @param outputColorFilter is a required param that will be populated by * this function if the bitmap's colorspace is not sRGB. If populated the * filter will convert colors from the bitmaps colorspace into sRGB. It * is the callers responsibility to use this colorFilter when drawing * this image into any destination that is presumed to be sRGB (i.e. a * buffer that has no colorspace defined). */ sk_sp<SkImage> makeImage(sk_sp<SkColorFilter>* outputColorFilter); private: virtual ~Bitmap(); void* getStorage() const; Loading Loading
core/jni/android/graphics/Shader.cpp +10 −8 Original line number Diff line number Diff line #include "GraphicsJNI.h" #include "SkColorFilter.h" #include "SkGradientShader.h" #include "SkImagePriv.h" #include "SkShader.h" Loading Loading @@ -64,28 +65,29 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j jint tileModeX, jint tileModeY) { const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr); sk_sp<SkImage> image; sk_sp<SkColorFilter> colorFilter; if (jbitmap) { // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise, // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility. image = android::bitmap::toBitmap(env, jbitmap).makeImage(); image = android::bitmap::toBitmap(env, jbitmap).makeImage(&colorFilter); } if (!image.get()) { SkBitmap bitmap; image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode); } sk_sp<SkShader> baseShader = image->makeShader( sk_sp<SkShader> shader = image->makeShader( (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY); SkShader* shader; if (matrix) { shader = baseShader->makeWithLocalMatrix(*matrix).release(); } else { shader = baseShader.release(); shader = shader->makeWithLocalMatrix(*matrix); } if(colorFilter) { shader = shader->makeWithColorFilter(colorFilter); } ThrowIAE_IfNull(env, shader); return reinterpret_cast<jlong>(shader); ThrowIAE_IfNull(env, shader.get()); return reinterpret_cast<jlong>(shader.release()); } /////////////////////////////////////////////////////////////////////////////////////////////// Loading
libs/hwui/GlopBuilder.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -296,6 +296,7 @@ void GlopBuilder::setFill(int color, float alphaScale, colorVector[2] = EOCF(srcColorMatrix[14] / 255.0f); colorVector[3] = srcColorMatrix[19] / 255.0f; // alpha is linear } else { ALOGE("unsupported ColorFilter type: %s", colorFilter->getTypeName()); LOG_ALWAYS_FATAL("unsupported ColorFilter"); } } else { Loading
libs/hwui/SkiaCanvas.cpp +48 −13 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #include "pipeline/skia/AnimatedDrawables.h" #include <SkCanvasStateUtils.h> #include <SkColorFilter.h> // TODO remove me! #include <SkColorSpaceXformCanvas.h> #include <SkDrawable.h> #include <SkDeque.h> Loading Loading @@ -529,25 +531,49 @@ void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, cons // Canvas draw operations: Bitmaps // ---------------------------------------------------------------------------- inline static const SkPaint* addFilter(const SkPaint* origPaint, SkPaint* tmpPaint, sk_sp<SkColorFilter> colorFilter) { if (colorFilter) { if (origPaint) { *tmpPaint = *origPaint; } tmpPaint->setColorFilter(colorFilter); return tmpPaint; } else { return origPaint; } } void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) { mCanvas->drawImage(bitmap.makeImage(), left, top, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImage(image, left, top, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix, const SkPaint* paint) { void SkiaCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) { SkAutoCanvasRestore acr(mCanvas, true); mCanvas->concat(matrix); mCanvas->drawImage(hwuiBitmap.makeImage(), 0, 0, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImage(image, 0, 0, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop, void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom); SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); mCanvas->drawImageRect(hwuiBitmap.makeImage(), srcRect, dstRect, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImageRect(image, srcRect, dstRect, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeight, void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, const float* vertices, const int* colors, const SkPaint* paint) { const int ptCount = (meshWidth + 1) * (meshHeight + 1); const int indexCount = meshWidth * meshHeight * 6; Loading @@ -565,8 +591,8 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeigh // cons up texture coordinates and indices { const SkScalar w = SkIntToScalar(hwuiBitmap.width()); const SkScalar h = SkIntToScalar(hwuiBitmap.height()); const SkScalar w = SkIntToScalar(bitmap.width()); const SkScalar h = SkIntToScalar(bitmap.height()); const SkScalar dx = w / meshWidth; const SkScalar dy = h / meshHeight; Loading Loading @@ -627,17 +653,22 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& hwuiBitmap, int meshWidth, int meshHeigh tmpPaint = *paint; } sk_sp<SkImage> image = hwuiBitmap.makeImage(); tmpPaint.setShader(image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)); sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); sk_sp<SkShader> shader = image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); if(colorFilter) { shader = shader->makeWithColorFilter(colorFilter); } tmpPaint.setShader(shader); mCanvas->drawVertices(builder.detach(), SkBlendMode::kModulate, tmpPaint); } void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk, void SkiaCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) { SkCanvas::Lattice lattice; NinePatchUtils::SetLatticeDivs(&lattice, chunk, hwuiBitmap.width(), hwuiBitmap.height()); NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height()); lattice.fFlags = nullptr; int numFlags = 0; Loading @@ -654,7 +685,11 @@ void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk, lattice.fBounds = nullptr; SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); mCanvas->drawImageLattice(hwuiBitmap.makeImage().get(), lattice, dst, paint); SkPaint tmpPaint; sk_sp<SkColorFilter> colorFilter; sk_sp<SkImage> image = bitmap.makeImage(&colorFilter); mCanvas->drawImageLattice(image.get(), lattice, dst, addFilter(paint, &tmpPaint, colorFilter)); } void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) { Loading
libs/hwui/hwui/Bitmap.cpp +8 −11 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <ui/PixelFormat.h> #include <SkCanvas.h> #include <SkToSRGBColorFilter.h> #include <SkImagePriv.h> namespace android { Loading Loading @@ -208,11 +209,8 @@ Bitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info) buffer->incStrong(buffer); setImmutable(); // HW bitmaps are always immutable if (uirenderer::Properties::isSkiaEnabled()) { // GraphicBuffer should be in the display color space (Bitmap::createFrom is always // passing SRGB). The code that uploads into a GraphicBuffer should do color conversion if // needed. mImage = SkImage::MakeFromAHardwareBuffer(reinterpret_cast<AHardwareBuffer*>(buffer), mInfo.alphaType(), nullptr); mInfo.alphaType(), mInfo.refColorSpace()); } } Loading Loading @@ -319,7 +317,7 @@ GraphicBuffer* Bitmap::graphicBuffer() { return nullptr; } sk_sp<SkImage> Bitmap::makeImage() { sk_sp<SkImage> Bitmap::makeImage(sk_sp<SkColorFilter>* outputColorFilter) { sk_sp<SkImage> image = mImage; if (!image) { SkASSERT(!(isHardware() && uirenderer::Properties::isSkiaEnabled())); Loading @@ -330,12 +328,11 @@ sk_sp<SkImage> Bitmap::makeImage() { // Note we don't cache in this case, because the raster image holds a pointer to this Bitmap // internally and ~Bitmap won't be invoked. // TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here. if (uirenderer::Properties::isSkiaEnabled()) { image = SkMakeImageInColorSpace(skiaBitmap, SkColorSpace::MakeSRGB(), skiaBitmap.getGenerationID(), kNever_SkCopyPixelsMode); } else { image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode); } if(uirenderer::Properties::isSkiaEnabled() && image->colorSpace() != nullptr && !image->colorSpace()->isSRGB()) { *outputColorFilter = SkToSRGBColorFilter::Make(image->refColorSpace()); } return image; } Loading
libs/hwui/hwui/Bitmap.h +13 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <SkBitmap.h> #include <SkColorFilter.h> #include <SkColorSpace.h> #include <SkImage.h> #include <SkImageInfo.h> Loading Loading @@ -96,9 +97,18 @@ public: GraphicBuffer* graphicBuffer(); // makeImage creates or returns a cached SkImage. Can be invoked from UI or render thread. // Caching is supported only for HW Bitmaps with skia pipeline. sk_sp<SkImage> makeImage(); /** * Creates or returns a cached SkImage and is safe to be invoked from either * the UI or RenderThread. * * @param outputColorFilter is a required param that will be populated by * this function if the bitmap's colorspace is not sRGB. If populated the * filter will convert colors from the bitmaps colorspace into sRGB. It * is the callers responsibility to use this colorFilter when drawing * this image into any destination that is presumed to be sRGB (i.e. a * buffer that has no colorspace defined). */ sk_sp<SkImage> makeImage(sk_sp<SkColorFilter>* outputColorFilter); private: virtual ~Bitmap(); void* getStorage() const; Loading