Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62feb3a0 authored by Matt Sarett's avatar Matt Sarett
Browse files

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
parent 682ad3b4
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
#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,
    sk_sp<SkShader> s = SkMakeBitmapShader(bitmap,
                                           (SkShader::TileMode)tileModeX,
                                        (SkShader::TileMode)tileModeY);
                                           (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());
}

///////////////////////////////////////////////////////////////////////////////////////////////
+8 −4
Original line number Diff line number Diff line
@@ -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,
    sk_sp<SkShader> shader = SkMakeBitmapShader(bitmap,
                                                SkShader::kClamp_TileMode,
                                                    SkShader::kClamp_TileMode);
    SkSafeUnref(tmpPaint.setShader(shader));
                                                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,
+16 −10
Original line number Diff line number Diff line
@@ -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();
+7 −3
Original line number Diff line number Diff line
@@ -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];