move clip-stencil function into GpuDevice

Will follow-up with a change that doesn't use SkRegions!

Note:

The previous code flow gathered a region for all devices (in the canvas method).
However, it only tried to draw into the top device. The new code just focuses on
the top device, which ought to give the same results.

Change-Id: Ic5ed47e7908d646700c09b10faa538415522c645
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/261283
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Mike Reed 2019-12-20 14:59:49 -05:00 committed by Skia Commit-Bot
parent c15afe488b
commit aebe4390af
5 changed files with 35 additions and 65 deletions

View File

@ -11,50 +11,16 @@
#include "src/core/SkDevice.h"
#include "src/image/SkSurface_Base.h"
#if SK_SUPPORT_GPU
#include "src/gpu/GrClip.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrStyle.h"
#include "src/gpu/GrUserStencilSettings.h"
#include "src/gpu/effects/GrDisableColorXP.h"
#endif //SK_SUPPORT_GPU
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
#include <log/log.h>
#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;
return device && device->android_utils_clipWithStencil();
}
#endif //SK_SUPPORT_GPU
#endif
void SkAndroidFrameworkUtils::SafetyNetLog(const char* bugNumber) {
android_errorWriteLog(0x534e4554, bugNumber);

View File

@ -131,6 +131,8 @@ public:
void setGlobalCTM(const SkMatrix& ctm);
virtual void validateDevBounds(const SkIRect&) {}
virtual bool android_utils_clipWithStencil() { return false; }
protected:
enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled

View File

@ -1667,3 +1667,32 @@ SkImageFilterCache* SkGpuDevice::getImageFilterCache() {
return SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize);
}
////////////////////////////////////////////////////////////////////////////////////
bool SkGpuDevice::android_utils_clipWithStencil() {
SkRegion clipRegion;
this->onAsRgnClip(&clipRegion);
if (clipRegion.isEmpty()) {
return false;
}
GrRenderTargetContext* rtc = this->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;
}

View File

@ -126,6 +126,8 @@ public:
bool onAccessPixels(SkPixmap*) override;
bool android_utils_clipWithStencil() override;
protected:
bool onReadPixels(const SkPixmap&, int, int) override;
bool onWritePixels(const SkPixmap&, int, int) override;

View File

@ -1563,32 +1563,3 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) {
}
#endif
}
DEF_GPUTEST_FOR_ALL_CONTEXTS(canvas_private_clipRgn, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
const int w = 10;
const int h = 10;
SkImageInfo info = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
SkCanvas* canvas = surf->getCanvas();
SkRegion rgn;
canvas->temporary_internal_getRgnClip(&rgn);
REPORTER_ASSERT(reporter, rgn.isRect());
REPORTER_ASSERT(reporter, rgn.getBounds() == SkIRect::MakeWH(w, h));
canvas->save();
canvas->clipRect(SkRect::MakeWH(5, 5), kDifference_SkClipOp);
canvas->temporary_internal_getRgnClip(&rgn);
REPORTER_ASSERT(reporter, rgn.isComplex());
REPORTER_ASSERT(reporter, rgn.getBounds() == SkIRect::MakeWH(w, h));
canvas->restore();
canvas->save();
canvas->clipRRect(SkRRect::MakeOval(SkRect::MakeLTRB(3, 3, 7, 7)));
canvas->temporary_internal_getRgnClip(&rgn);
REPORTER_ASSERT(reporter, rgn.isComplex());
REPORTER_ASSERT(reporter, rgn.getBounds() == SkIRect::MakeLTRB(3, 3, 7, 7));
canvas->restore();
}