Add a private API for writing the clip to the stencil

Add a private API used by Android framework, which writes the clip
into a stencil buffer. This is used by HWUI to clip the WebView.

Bug: 31489986
Change-Id: I94515f1539acd9d069c8aceb3300577feed9c94f
Reviewed-on: https://skia-review.googlesource.com/29521
Commit-Queue: Stan Iliev <stani@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
This commit is contained in:
Stan Iliev 2017-08-02 15:36:24 -04:00 committed by Skia Commit-Bot
parent dcba08e891
commit 73d8fd9065
9 changed files with 110 additions and 6 deletions

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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<GrDrawOp> op = GrRegionOp::Make(std::move(paint), viewMatrix, region, aaType);
std::unique_ptr<GrDrawOp> op = GrRegionOp::Make(std::move(paint), viewMatrix, region, aaType,
ss);
this->addDrawOp(clip, std::move(op));
}

View File

@ -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.

View File

@ -169,11 +169,11 @@ private:
namespace GrRegionOp {
std::unique_ptr<GrDrawOp> 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);
}
}

View File

@ -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<GrDrawOp> Make(GrPaint&&, const SkMatrix& viewMatrix, const SkRegion&, GrAAType);
std::unique_ptr<GrDrawOp> Make(GrPaint&&, const SkMatrix& viewMatrix, const SkRegion&, GrAAType,
const GrUserStencilSettings* stencilSettings = nullptr);
}
#endif