Use SkMakeBitmapShader, avoid bitmap copy
CreateBitmapShader now forces a copy. This updates the call sites to use SkMakeBitmapShader (in SkImagePriv.h) with kNever_SkCopyPixelsMode. This maintains the behavior where apps can modify the bitmap in the shader after creating the shader. This also ensures that the texture cache will work (since it's based off of SkPixelRefs). BUG:31594626 Change-Id: Ic75cb6cdc05c750b7946208e48a8127838d9c2f8
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "GraphicsJNI.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkImagePriv.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkXfermode.h"
|
||||
#include "core_jni_helpers.h"
|
||||
@@ -94,12 +95,15 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap,
|
||||
// we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
|
||||
GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
|
||||
}
|
||||
SkShader* s = SkShader::CreateBitmapShader(bitmap,
|
||||
(SkShader::TileMode)tileModeX,
|
||||
(SkShader::TileMode)tileModeY);
|
||||
sk_sp<SkShader> s = SkMakeBitmapShader(bitmap,
|
||||
(SkShader::TileMode)tileModeX,
|
||||
(SkShader::TileMode)tileModeY,
|
||||
nullptr,
|
||||
kNever_SkCopyPixelsMode,
|
||||
nullptr);
|
||||
|
||||
ThrowIAE_IfNull(env, s);
|
||||
return reinterpret_cast<jlong>(s);
|
||||
ThrowIAE_IfNull(env, s.get());
|
||||
return reinterpret_cast<jlong>(s.release());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <SkDrawFilter.h>
|
||||
#include <SkGraphics.h>
|
||||
#include <SkImage.h>
|
||||
#include <SkImagePriv.h>
|
||||
#include <SkRSXform.h>
|
||||
#include <SkShader.h>
|
||||
#include <SkTemplates.h>
|
||||
@@ -593,10 +594,13 @@ void SkiaCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshH
|
||||
if (paint) {
|
||||
tmpPaint = *paint;
|
||||
}
|
||||
SkShader* shader = SkShader::CreateBitmapShader(bitmap,
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode);
|
||||
SkSafeUnref(tmpPaint.setShader(shader));
|
||||
sk_sp<SkShader> shader = SkMakeBitmapShader(bitmap,
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode,
|
||||
nullptr,
|
||||
kNever_SkCopyPixelsMode,
|
||||
nullptr);
|
||||
tmpPaint.setShader(std::move(shader));
|
||||
|
||||
mCanvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, (SkPoint*)vertices,
|
||||
texs, (const SkColor*)colors, NULL, indices,
|
||||
|
||||
@@ -740,10 +740,13 @@ TEST(RecordingCanvas, refBitmapInShader_bitmapShader) {
|
||||
SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
|
||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
|
||||
SkPaint paint;
|
||||
SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(bitmap,
|
||||
sk_sp<SkShader> shader = SkMakeBitmapShader(bitmap,
|
||||
SkShader::TileMode::kClamp_TileMode,
|
||||
SkShader::TileMode::kClamp_TileMode));
|
||||
paint.setShader(shader);
|
||||
SkShader::TileMode::kClamp_TileMode,
|
||||
nullptr,
|
||||
kNever_SkCopyPixelsMode,
|
||||
nullptr);
|
||||
paint.setShader(std::move(shader));
|
||||
canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
|
||||
});
|
||||
auto& bitmaps = dl->getBitmapResources();
|
||||
@@ -754,21 +757,24 @@ TEST(RecordingCanvas, refBitmapInShader_composeShader) {
|
||||
SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
|
||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
|
||||
SkPaint paint;
|
||||
SkAutoTUnref<SkShader> shader1(SkShader::CreateBitmapShader(bitmap,
|
||||
sk_sp<SkShader> shader1 = SkMakeBitmapShader(bitmap,
|
||||
SkShader::TileMode::kClamp_TileMode,
|
||||
SkShader::TileMode::kClamp_TileMode));
|
||||
SkShader::TileMode::kClamp_TileMode,
|
||||
nullptr,
|
||||
kNever_SkCopyPixelsMode,
|
||||
nullptr);
|
||||
|
||||
SkPoint center;
|
||||
center.set(50, 50);
|
||||
SkColor colors[2];
|
||||
colors[0] = Color::Black;
|
||||
colors[1] = Color::White;
|
||||
SkAutoTUnref<SkShader> shader2(SkGradientShader::CreateRadial(center, 50, colors, nullptr, 2,
|
||||
SkShader::TileMode::kRepeat_TileMode));
|
||||
sk_sp<SkShader> shader2 = SkGradientShader::MakeRadial(center, 50, colors, nullptr, 2,
|
||||
SkShader::TileMode::kRepeat_TileMode);
|
||||
|
||||
SkAutoTUnref<SkShader> composeShader(SkShader::CreateComposeShader(shader1, shader2,
|
||||
SkXfermode::Mode::kMultiply_Mode));
|
||||
paint.setShader(composeShader);
|
||||
sk_sp<SkShader> composeShader = SkShader::MakeComposeShader(std::move(shader1), std::move(shader2),
|
||||
SkXfermode::Mode::kMultiply_Mode);
|
||||
paint.setShader(std::move(composeShader));
|
||||
canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
|
||||
});
|
||||
auto& bitmaps = dl->getBitmapResources();
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
#include "tests/common/TestUtils.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <SkShader.h>
|
||||
#include <SkColorMatrixFilter.h>
|
||||
#include <SkImagePriv.h>
|
||||
#include <SkShader.h>
|
||||
|
||||
using namespace android;
|
||||
using namespace android::uirenderer;
|
||||
@@ -29,10 +30,13 @@ using namespace android::uirenderer;
|
||||
*/
|
||||
TEST(SkiaBehavior, CreateBitmapShader1x1) {
|
||||
SkBitmap origBitmap = TestUtils::createSkBitmap(1, 1);
|
||||
SkAutoTUnref<SkShader> s(SkShader::CreateBitmapShader(
|
||||
sk_sp<SkShader> s = SkMakeBitmapShader(
|
||||
origBitmap,
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kRepeat_TileMode));
|
||||
SkShader::kRepeat_TileMode,
|
||||
nullptr,
|
||||
kNever_SkCopyPixelsMode,
|
||||
nullptr);
|
||||
|
||||
SkBitmap bitmap;
|
||||
SkShader::TileMode xy[2];
|
||||
|
||||
Reference in New Issue
Block a user