diff --git a/BUILD.gn b/BUILD.gn index d837d1db0a..08b94cd9cc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -678,6 +678,7 @@ component("skia") { sources += skia_utils_sources sources += skia_xps_sources sources += [ + "src/android/SkAndroidFrameworkUtils.cpp", "src/android/SkBitmapRegionCodec.cpp", "src/android/SkBitmapRegionDecoder.cpp", "src/codec/SkAndroidCodec.cpp", diff --git a/include/android/SkAndroidFrameworkUtils.h b/include/android/SkAndroidFrameworkUtils.h new file mode 100644 index 0000000000..0457d03534 --- /dev/null +++ b/include/android/SkAndroidFrameworkUtils.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkAndroidFrameworkUtils_DEFINED +#define SkAndroidFrameworkUtils_DEFINED + +#include "SkTypes.h" + +#ifdef SK_BUILD_FOR_ANDROID + +class SkCanvas; + +/** + * SkAndroidFrameworkUtils expose private APIs used only by Android framework. + */ +class SkAndroidFrameworkUtils { +public: + +#if SK_SUPPORT_GPU + /** + * clipWithStencil draws the current clip into a stencil buffer with reference value and mask + * set to 0x1. This function works only on a GPU canvas. + * + * @param canvas A GPU canvas that has a non-empty clip. + * + * @return true on success or false if clip is empty or not a GPU canvas. + */ + static bool clipWithStencil(SkCanvas* canvas); +#endif //SK_SUPPORT_GPU +}; + +#endif // SK_BUILD_FOR_ANDROID + +#endif // SkAndroidFrameworkUtils_DEFINED diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 8fbca71624..c4cb1752d8 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -17,6 +17,7 @@ class GrContext; class GrRenderTargetContext; +class SkAndroidFrameworkUtils; class SkBaseDevice; class SkBitmap; class SkClipStack; @@ -1457,6 +1458,7 @@ private: void checkForDeferredSave(); void internalSetMatrix(const SkMatrix&); + friend class SkAndroidFrameworkUtils; friend class SkDrawIter; // needs setupDrawForLayerDevice() friend class AutoDrawLooper; friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip diff --git a/src/android/SkAndroidFrameworkUtils.cpp b/src/android/SkAndroidFrameworkUtils.cpp new file mode 100644 index 0000000000..5fbc2cae18 --- /dev/null +++ b/src/android/SkAndroidFrameworkUtils.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkAndroidFrameworkUtils.h" +#include "SkCanvas.h" +#include "SkDevice.h" + +#if SK_SUPPORT_GPU +#include "GrStyle.h" +#include "GrClip.h" +#include "GrRenderTargetContext.h" +#include "GrUserStencilSettings.h" +#include "effects/GrDisableColorXP.h" +#endif //SK_SUPPORT_GPU + +#ifdef SK_BUILD_FOR_ANDROID + +#if SK_SUPPORT_GPU +bool SkAndroidFrameworkUtils::clipWithStencil(SkCanvas* canvas) { + SkRegion clipRegion; + canvas->temporary_internal_getRgnClip(&clipRegion); + if (clipRegion.isEmpty()) { + return false; + } + SkBaseDevice* device = canvas->getDevice(); + if (!device) { + return false; + } + GrRenderTargetContext* rtc = device->accessRenderTargetContext(); + if (!rtc) { + return false; + } + GrPaint grPaint; + grPaint.setXPFactory(GrDisableColorXPFactory::Get()); + GrNoClip noClip; + static constexpr GrUserStencilSettings kDrawToStencil( + GrUserStencilSettings::StaticInit< + 0x1, + GrUserStencilTest::kAlways, + 0x1, + GrUserStencilOp::kReplace, + GrUserStencilOp::kReplace, + 0x1>() + ); + rtc->drawRegion(noClip, std::move(grPaint), GrAA::kNo, SkMatrix::I(), clipRegion, + GrStyle::SimpleFill(), &kDrawToStencil); + return true; +} +#endif //SK_SUPPORT_GPU + +#endif // SK_BUILD_FOR_ANDROID + diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index c0aef8ed95..c531b1e18b 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -13,6 +13,7 @@ #include "SkColor.h" #include "SkSurfaceProps.h" +class SkAndroidFrameworkUtils; class SkBitmap; class SkDrawFilter; struct SkDrawShadowRec; @@ -346,6 +347,7 @@ protected: static void LogDrawScaleFactor(const SkMatrix&, SkFilterQuality); private: + friend class SkAndroidFrameworkUtils; friend class SkCanvas; friend struct DeviceCM; //for setMatrixClip friend class SkDraw; diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index d54b084b5a..cc82408b8b 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1277,7 +1277,8 @@ void GrRenderTargetContext::drawRegion(const GrClip& clip, GrAA aa, const SkMatrix& viewMatrix, const SkRegion& region, - const GrStyle& style) { + const GrStyle& style, + const GrUserStencilSettings* ss) { ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED SkDEBUGCODE(this->validate();) @@ -1300,7 +1301,8 @@ void GrRenderTargetContext::drawRegion(const GrClip& clip, } GrAAType aaType = this->chooseAAType(GrAA::kNo, GrAllowMixedSamples::kNo); - std::unique_ptr op = GrRegionOp::Make(std::move(paint), viewMatrix, region, aaType); + std::unique_ptr op = GrRegionOp::Make(std::move(paint), viewMatrix, region, aaType, + ss); this->addDrawOp(clip, std::move(op)); } diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 964d9e9a4e..d7d2b9b60c 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -246,7 +246,8 @@ public: GrAA aa, const SkMatrix& viewMatrix, const SkRegion& region, - const GrStyle& style); + const GrStyle& style, + const GrUserStencilSettings* ss = nullptr); /** * Draws an oval. diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp index f059ac76d7..7e2879c01d 100644 --- a/src/gpu/ops/GrRegionOp.cpp +++ b/src/gpu/ops/GrRegionOp.cpp @@ -169,11 +169,11 @@ private: namespace GrRegionOp { std::unique_ptr Make(GrPaint&& paint, const SkMatrix& viewMatrix, const SkRegion& region, - GrAAType aaType) { + GrAAType aaType, const GrUserStencilSettings* stencilSettings) { if (aaType != GrAAType::kNone && aaType != GrAAType::kMSAA) { return nullptr; } - return RegionOp::Make(std::move(paint), viewMatrix, region, aaType); + return RegionOp::Make(std::move(paint), viewMatrix, region, aaType, stencilSettings); } } diff --git a/src/gpu/ops/GrRegionOp.h b/src/gpu/ops/GrRegionOp.h index bfdad710fa..b74f78c74e 100644 --- a/src/gpu/ops/GrRegionOp.h +++ b/src/gpu/ops/GrRegionOp.h @@ -14,10 +14,12 @@ class GrDrawOp; class SkMatrix; class SkRegion; class GrPaint; +struct GrUserStencilSettings; namespace GrRegionOp { /** GrAAType must be kNone or kMSAA. */ -std::unique_ptr Make(GrPaint&&, const SkMatrix& viewMatrix, const SkRegion&, GrAAType); +std::unique_ptr Make(GrPaint&&, const SkMatrix& viewMatrix, const SkRegion&, GrAAType, + const GrUserStencilSettings* stencilSettings = nullptr); } #endif