Revert of Improve usage of window rectangles (patchset #9 id:160001 of https://codereview.chromium.org/2289363005/ )
Reason for revert: broke build. See https://build.chromium.org/p/client.skia/builders/Perf-Win8-MSVC-ShuttleA-GPU-GTX960-x86_64-Debug/builds/186 Original issue's description: > Improve usage of window rectangles > > * Skips non-AA diff rect elements and replaces them with window > rectangles. > * Places window rectangles in the interiors of antialiased diff rects. > * Arranges two overlapping window rectangles in a plus shape inside of > diff rounded rects. > * Enables window rectangles when clearing and generating clip masks. > > GTX 960 perf result (with vs. without window rectangles): > > glinst4 msaa16 gpu > keymobi_pinterest.skp 0.48 -> 0.17 [ 35%] 2.77 -> 1.49 [ 54%] 0.22 -> 0.16 [ 70%] > keymobi_digg_com.skp 0.42 -> 0.23 [ 55%] 2.34 -> 1.08 [ 46%] 0.25 -> 0.21 [ 83%] > desk_jsfiddlebigcar.skp 0.28 -> 0.16 [ 59%] 1.70 -> 0.96 [ 57%] 0.19 -> 0.14 [ 70%] > top25desk_wordpress.skp 0.45 -> 0.18 [ 40%] 2.78 -> 1.53 [ 55%] 0.21 -> 0.19 [ 94%] > top25desk_weather_com.skp 2.01 -> 1.93 [ 96%] 23.5 -> 2.54 [ 11%] 1.90 -> 1.68 [ 88%] > keymobi_blogger.skp 0.57 -> 0.37 [ 65%] 2.87 -> 1.54 [ 54%] 0.43 -> 0.33 [ 77%] > keymobi_linkedin.skp 0.32 -> 0.17 [ 51%] 1.93 -> 1.04 [ 54%] 0.17 -> 0.15 [ 91%] > keymobi_bing_com_search_... 0.29 -> 0.25 [ 83%] 1.85 -> 1.23 [ 66%] 0.50 -> 0.24 [ 48%] > keymobi_theverge_com_201... 1.00 -> 0.67 [ 68%] 9.46 -> 3.84 [ 41%] 0.72 -> 0.65 [ 90%] > keymobi_sfgate_com_.skp 1.56 -> 1.13 [ 72%] 4.49 -> 2.86 [ 64%] 1.54 -> 1.11 [ 72%] > keymobi_ftw_usatoday_com... 0.59 -> 0.34 [ 57%] 2.80 -> 1.54 [ 55%] 1.21 -> 1.20 [ 99%] > keymobi_shop_mobileweb_e... 0.46 -> 0.32 [ 70%] 2.60 -> 1.26 [ 48%] 0.35 -> 0.34 [ 97%] > keymobi_cnn_com.skp 0.68 -> 0.42 [ 63%] 3.40 -> 2.10 [ 62%] 0.49 -> 0.45 [ 93%] > keymobi_plus_google_com_... 0.77 -> 0.46 [ 60%] 4.83 -> 3.56 [ 74%] 0.52 -> 0.46 [ 89%] > keymobi_wordpress.skp 0.50 -> 0.40 [ 81%] 2.60 -> 1.31 [ 50%] 0.40 -> 0.37 [ 91%] > keymobi_androidpolice_co... 0.84 -> 0.73 [ 87%] 4.15 -> 2.05 [ 49%] 0.77 -> 0.67 [ 87%] > keymobi_online_wsj_com_h... 0.55 -> 0.43 [ 78%] 2.91 -> 1.66 [ 57%] 0.45 -> 0.41 [ 90%] > keymobi_iphone_capitolvo... 1.18 -> 0.96 [ 81%] 6.26 -> 4.96 [ 79%] 0.95 -> 0.92 [ 97%] > keymobi_wikipedia__1_tab... 0.46 -> 0.41 [ 89%] 2.51 -> 1.24 [ 49%] 0.40 -> 0.38 [ 95%] > keymobi_wikipedia__1_tab... 0.46 -> 0.42 [ 90%] 2.52 -> 1.25 [ 50%] 0.40 -> 0.38 [ 96%] > keymobi_boingboing_net.skp 0.62 -> 0.56 [ 90%] 3.15 -> 1.80 [ 57%] 0.61 -> 0.56 [ 92%] > keymobi_cnn_com_2012_10_... 0.86 -> 0.82 [ 95%] 2.81 -> 1.50 [ 53%] 0.91 -> 0.83 [ 91%] > top25desk_techcrunch_com... 0.61 -> 0.56 [ 92%] 3.03 -> 1.76 [ 58%] 0.62 -> 0.56 [ 91%] > top25desk_ebay_com.skp 1.18 -> 1.08 [ 92%] 2.23 -> 1.24 [ 56%] 1.14 -> 1.09 [ 96%] > desk_css3gradients.skp 0.64 -> 0.61 [ 95%] 2.99 -> 1.54 [ 52%] 0.62 -> 0.61 [ 99%] > top25desk_blogger.skp 0.61 -> 0.59 [ 96%] 2.50 -> 1.37 [ 55%] 0.60 -> 0.57 [ 95%] > keymobi_nytimes_com_.skp 0.65 -> 0.64 [ 98%] 2.69 -> 1.42 [ 53%] 0.62 -> 0.59 [ 96%] > keymobi_wowwiki_com_worl... 0.99 -> 0.92 [ 92%] 3.46 -> 2.06 [ 60%] 0.98 -> 0.95 [ 96%] > keymobi_cuteoverload_com... 1.37 -> 1.26 [ 92%] 3.24 -> 2.45 [ 76%] 1.38 -> 1.35 [ 98%] > keymobi_mobile_news_sand... 0.88 -> 0.81 [ 93%] 3.50 -> 2.07 [ 59%] 0.82 -> 0.81 [100%] > top25desk_linkedin.skp 0.87 -> 0.87 [100%] 2.92 -> 1.73 [ 59%] 0.94 -> 0.86 [ 91%] > top25desk_docs___1_open_... 1.43 -> 1.36 [ 95%] 1.87 -> 1.42 [ 76%] 0.73 -> 0.66 [ 91%] > keymobi_reddit_com_r_pro... 0.68 -> 0.66 [ 96%] 2.49 -> 1.23 [ 49%] 0.65 -> 0.66 [102%] > ... > > BUG=skia: > GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2289363005 > > Committed: https://skia.googlesource.com/skia/+/db42be9a326c747ff92ed1da8c3536c5b3e8e22b TBR=bsalomon@google.com,egdaniel@google.com,robertphillips@google.com,csmartdalton@google.com # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=skia: Review-Url: https://codereview.chromium.org/2312173002
This commit is contained in:
parent
e6088c6063
commit
c3bfcb803a
@ -1,305 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
#include "SkClipStack.h"
|
||||
#include "SkRRect.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
# include "GrAppliedClip.h"
|
||||
# include "GrDrawContext.h"
|
||||
# include "GrDrawContextPriv.h"
|
||||
# include "GrFixedClip.h"
|
||||
# include "GrReducedClip.h"
|
||||
# include "GrRenderTargetPriv.h"
|
||||
# include "GrResourceProvider.h"
|
||||
# include "effects/GrTextureDomain.h"
|
||||
#endif
|
||||
|
||||
constexpr static SkIRect kDeviceRect = {0, 0, 600, 600};
|
||||
constexpr static SkIRect kLayerRect = {25, 25, 575, 575};
|
||||
constexpr static SkIRect kCoverRect = {50, 50, 550, 550};
|
||||
|
||||
namespace skiagm {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class WindowRectanglesBaseGM : public GM {
|
||||
protected:
|
||||
virtual void onCoverClipStack(const SkClipStack&, SkCanvas*) = 0;
|
||||
|
||||
private:
|
||||
SkISize onISize() override { return SkISize::Make(kDeviceRect.width(), kDeviceRect.height()); }
|
||||
void onDraw(SkCanvas*) final;
|
||||
};
|
||||
|
||||
void WindowRectanglesBaseGM::onDraw(SkCanvas* canvas) {
|
||||
sk_tool_utils::draw_checkerboard(canvas, 0xffffffff, 0xffc6c3c6, 25);
|
||||
canvas->saveLayer(SkRect::Make(kLayerRect), nullptr);
|
||||
|
||||
SkClipStack stack;
|
||||
stack.clipDevRect(SkRect::MakeXYWH(370.75, 80.25, 149, 100), SkRegion::kDifference_Op, false);
|
||||
stack.clipDevRect(SkRect::MakeXYWH(80.25, 420.75, 150, 100), SkRegion::kDifference_Op, true);
|
||||
stack.clipDevRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(200, 200, 200, 200), 60, 45),
|
||||
SkRegion::kDifference_Op, true);
|
||||
|
||||
SkRRect nine;
|
||||
nine.setNinePatch(SkRect::MakeXYWH(550 - 30.25 - 100, 370.75, 100, 150), 12, 35, 23, 20);
|
||||
stack.clipDevRRect(nine, SkRegion::kDifference_Op, true);
|
||||
|
||||
SkRRect complx;
|
||||
SkVector complxRadii[4] = {{6, 4}, {8, 12}, {16, 24}, {48, 32}};
|
||||
complx.setRectRadii(SkRect::MakeXYWH(80.25, 80.75, 100, 149), complxRadii);
|
||||
stack.clipDevRRect(complx, SkRegion::kDifference_Op, false);
|
||||
|
||||
this->onCoverClipStack(stack, canvas);
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Draws a clip that will exercise window rectangles if they are supported.
|
||||
*/
|
||||
class WindowRectanglesGM : public WindowRectanglesBaseGM {
|
||||
private:
|
||||
SkString onShortName() final { return SkString("windowrectangles"); }
|
||||
void onCoverClipStack(const SkClipStack&, SkCanvas*) final;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a simple helper class for resetting a canvas's clip to our test’s SkClipStack.
|
||||
*/
|
||||
class ReplayClipStackVisitor final : public SkCanvasClipVisitor {
|
||||
public:
|
||||
typedef SkRegion::Op Op;
|
||||
ReplayClipStackVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
|
||||
void clipRect(const SkRect& r, Op op, bool aa) override { fCanvas->clipRect(r, op, aa); }
|
||||
void clipRRect(const SkRRect& rr, Op op, bool aa) override { fCanvas->clipRRect(rr, op, aa); }
|
||||
void clipPath(const SkPath&, Op, bool) override { SkFAIL("Not implemented"); }
|
||||
private:
|
||||
SkCanvas* const fCanvas;
|
||||
};
|
||||
|
||||
void WindowRectanglesGM::onCoverClipStack(const SkClipStack& stack, SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
paint.setColor(0xff00aa80);
|
||||
|
||||
// Set up the canvas's clip to match our SkClipStack.
|
||||
ReplayClipStackVisitor visitor(canvas);
|
||||
SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
|
||||
for (const SkClipStack::Element* element = iter.next(); element; element = iter.next()) {
|
||||
element->replay(&visitor);
|
||||
}
|
||||
|
||||
canvas->drawRect(SkRect::Make(kCoverRect), paint);
|
||||
}
|
||||
|
||||
DEF_GM( return new WindowRectanglesGM(); )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
constexpr static int kNumWindows = 8;
|
||||
|
||||
/**
|
||||
* Visualizes the mask (alpha or stencil) for a clip with several window rectangles. The purpose of
|
||||
* this test is to verify that window rectangles are being used during clip mask generation, and to
|
||||
* visualize where the window rectangles are placed.
|
||||
*
|
||||
* We use window rectangles when generating the clip mask because there is no need to invest time
|
||||
* defining those regions where window rectangles will be in effect during the actual draw anyway.
|
||||
*
|
||||
* This test works by filling the entire clip mask with a small checkerboard pattern before drawing
|
||||
* it, and then covering the mask with a solid color once it has been generated. The regions inside
|
||||
* window rectangles or outside the scissor should still have the initial checkerboard intact.
|
||||
*/
|
||||
class WindowRectanglesMaskGM : public WindowRectanglesBaseGM {
|
||||
private:
|
||||
constexpr static int kMaskCheckerSize = 5;
|
||||
SkString onShortName() final { return SkString("windowrectangles_mask"); }
|
||||
void onCoverClipStack(const SkClipStack&, SkCanvas*) final;
|
||||
void visualizeAlphaMask(GrContext*, GrDrawContext*, const GrReducedClip&, const GrPaint&);
|
||||
void visualizeStencilMask(GrContext*, GrDrawContext*, const GrReducedClip&, const GrPaint&);
|
||||
void stencilCheckerboard(GrDrawContext*, bool flip);
|
||||
void fail(SkCanvas*);
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for GrClips that visualize a clip mask.
|
||||
*/
|
||||
class MaskOnlyClipBase : public GrClip {
|
||||
private:
|
||||
bool quickContains(const SkRect&) const final { return false; }
|
||||
bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const final { return false; }
|
||||
void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
|
||||
rect->set(0, 0, width, height);
|
||||
if (iior) {
|
||||
*iior = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class clips a cover by an alpha mask. We use it to visualize the alpha clip mask.
|
||||
*/
|
||||
class AlphaOnlyClip final : public MaskOnlyClipBase {
|
||||
public:
|
||||
AlphaOnlyClip(GrTexture* mask, int x, int y) {
|
||||
int w = mask->width(), h = mask->height();
|
||||
SkMatrix mat = SkMatrix::MakeScale(1.f / SkIntToScalar(w), 1.f / SkIntToScalar(h));
|
||||
mat.preTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
fFP = GrTextureDomainEffect::Make(
|
||||
mask, nullptr, mat,
|
||||
GrTextureDomain::MakeTexelDomain(mask, SkIRect::MakeWH(w, h)),
|
||||
GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode,
|
||||
kDevice_GrCoordSet);
|
||||
|
||||
}
|
||||
private:
|
||||
bool apply(GrContext*, GrDrawContext*, bool, bool, GrAppliedClip* out) const override {
|
||||
out->addCoverageFP(fFP);
|
||||
return true;
|
||||
}
|
||||
sk_sp<GrFragmentProcessor> fFP;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class clips a cover by the stencil clip bit. We use it to visualize the stencil mask.
|
||||
*/
|
||||
class StencilOnlyClip final : public MaskOnlyClipBase {
|
||||
private:
|
||||
bool apply(GrContext*, GrDrawContext*, bool, bool, GrAppliedClip* out) const override {
|
||||
out->addStencilClip();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void WindowRectanglesMaskGM::onCoverClipStack(const SkClipStack& stack, SkCanvas* canvas) {
|
||||
GrContext* ctx = canvas->getGrContext();
|
||||
GrDrawContext* dc = canvas->internal_private_accessTopLayerDrawContext();
|
||||
|
||||
if (!ctx || !dc ||
|
||||
dc->accessRenderTarget()->renderTargetPriv().maxWindowRectangles() < kNumWindows) {
|
||||
this->fail(canvas);
|
||||
return;
|
||||
}
|
||||
|
||||
const GrReducedClip reducedClip(stack, SkRect::Make(kCoverRect), kNumWindows);
|
||||
|
||||
GrPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
if (!dc->isStencilBufferMultisampled()) {
|
||||
paint.setColor4f(GrColor4f(0, 0.25f, 1, 1));
|
||||
this->visualizeAlphaMask(ctx, dc, reducedClip, paint);
|
||||
} else {
|
||||
paint.setColor4f(GrColor4f(1, 0.25f, 0.25f, 1));
|
||||
this->visualizeStencilMask(ctx, dc, reducedClip, paint);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowRectanglesMaskGM::visualizeAlphaMask(GrContext* ctx, GrDrawContext* dc,
|
||||
const GrReducedClip& reducedClip,
|
||||
const GrPaint& paint) {
|
||||
GrPixelConfig config = kRGBA_8888_GrPixelConfig;
|
||||
if (ctx->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
|
||||
config = kAlpha_8_GrPixelConfig;
|
||||
}
|
||||
|
||||
sk_sp<GrDrawContext> maskDC(ctx->makeDrawContext(SkBackingFit::kExact, kLayerRect.width(),
|
||||
kLayerRect.height(), config, nullptr));
|
||||
if (!maskDC ||
|
||||
!ctx->resourceProvider()->attachStencilAttachment(maskDC->accessRenderTarget())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw a checker pattern into the alpha mask so we can visualize the regions left untouched by
|
||||
// the clip mask generation.
|
||||
this->stencilCheckerboard(maskDC.get(), true);
|
||||
maskDC->clear(nullptr, GrColorPackA4(0xff), true);
|
||||
maskDC->drawContextPriv().drawAndStencilRect(StencilOnlyClip(), &GrUserStencilSettings::kUnused,
|
||||
SkRegion::kDifference_Op, false, false,
|
||||
SkMatrix::I(),
|
||||
SkRect::MakeIWH(maskDC->width(), maskDC->height()));
|
||||
reducedClip.drawAlphaClipMask(maskDC.get());
|
||||
sk_sp<GrTexture> mask(maskDC->asTexture());
|
||||
|
||||
int x = kCoverRect.x() - kLayerRect.x(),
|
||||
y = kCoverRect.y() - kLayerRect.y();
|
||||
|
||||
// Now visualize the alpha mask by drawing a rect over the area where it is defined. The regions
|
||||
// inside window rectangles or outside the scissor should still have the initial checkerboard
|
||||
// intact. (This verifies we didn't spend any time modifying those pixels in the mask.)
|
||||
AlphaOnlyClip clip(mask.get(), x, y);
|
||||
dc->drawRect(clip, paint, SkMatrix::I(),
|
||||
SkRect::Make(SkIRect::MakeXYWH(x, y, mask->width(), mask->height())));
|
||||
}
|
||||
|
||||
void WindowRectanglesMaskGM::visualizeStencilMask(GrContext* ctx, GrDrawContext* dc,
|
||||
const GrReducedClip& reducedClip,
|
||||
const GrPaint& paint) {
|
||||
if (!ctx->resourceProvider()->attachStencilAttachment(dc->accessRenderTarget())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw a checker pattern into the stencil buffer so we can visualize the regions left untouched
|
||||
// by the clip mask generation.
|
||||
this->stencilCheckerboard(dc, false);
|
||||
reducedClip.drawStencilClipMask(ctx, dc, {kLayerRect.x(), kLayerRect.y()});
|
||||
|
||||
// Now visualize the stencil mask by covering the entire render target. The regions inside
|
||||
// window rectangless or outside the scissor should still have the initial checkerboard intact.
|
||||
// (This verifies we didn't spend any time modifying those pixels in the mask.)
|
||||
dc->drawPaint(StencilOnlyClip(), paint, SkMatrix::I());
|
||||
}
|
||||
|
||||
void WindowRectanglesMaskGM::stencilCheckerboard(GrDrawContext* dc, bool flip) {
|
||||
constexpr static GrUserStencilSettings kSetClip(
|
||||
GrUserStencilSettings::StaticInit<
|
||||
0,
|
||||
GrUserStencilTest::kAlways,
|
||||
0,
|
||||
GrUserStencilOp::kSetClipBit,
|
||||
GrUserStencilOp::kKeep,
|
||||
0>()
|
||||
);
|
||||
|
||||
dc->drawContextPriv().clearStencilClip(GrFixedClip::Disabled(), false);
|
||||
|
||||
for (int y = 0; y < kLayerRect.height(); y += kMaskCheckerSize) {
|
||||
for (int x = (y & 1) == flip ? 0 : kMaskCheckerSize;
|
||||
x < kLayerRect.width(); x += 2 * kMaskCheckerSize) {
|
||||
SkIRect checker = SkIRect::MakeXYWH(x, y, kMaskCheckerSize, kMaskCheckerSize);
|
||||
dc->drawContextPriv().stencilRect(GrNoClip(), &kSetClip, false, SkMatrix::I(),
|
||||
SkRect::Make(checker));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowRectanglesMaskGM::fail(SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setTextAlign(SkPaint::kCenter_Align);
|
||||
paint.setTextSize(20);
|
||||
sk_tool_utils::set_portable_typeface(&paint);
|
||||
|
||||
SkString errorMsg;
|
||||
errorMsg.printf("Requires GPU with %i window rectangles", kNumWindows);
|
||||
|
||||
canvas->clipRect(SkRect::Make(kCoverRect));
|
||||
canvas->clear(SK_ColorWHITE);
|
||||
canvas->drawText(errorMsg.c_str(), errorMsg.size(), SkIntToScalar(kCoverRect.centerX()),
|
||||
SkIntToScalar(kCoverRect.centerY() - 10), paint);
|
||||
}
|
||||
|
||||
DEF_GM( return new WindowRectanglesMaskGM(); )
|
||||
|
||||
#endif
|
||||
|
||||
}
|
@ -170,7 +170,6 @@
|
||||
'<(skia_src_path)/gpu/GrResourceHandle.h',
|
||||
'<(skia_src_path)/gpu/GrResourceProvider.cpp',
|
||||
'<(skia_src_path)/gpu/GrResourceProvider.h',
|
||||
'<(skia_src_path)/gpu/GrScissorState.h',
|
||||
'<(skia_src_path)/gpu/GrShape.cpp',
|
||||
'<(skia_src_path)/gpu/GrShape.h',
|
||||
'<(skia_src_path)/gpu/GrStencilAttachment.cpp',
|
||||
@ -205,7 +204,6 @@
|
||||
'<(skia_src_path)/gpu/GrTRecorder.h',
|
||||
'<(skia_src_path)/gpu/GrUserStencilSettings.h',
|
||||
'<(skia_src_path)/gpu/GrWindowRectangles.h',
|
||||
'<(skia_src_path)/gpu/GrWindowRectsState.h',
|
||||
'<(skia_src_path)/gpu/GrXferProcessor.cpp',
|
||||
'<(skia_src_path)/gpu/GrYUVProvider.cpp',
|
||||
'<(skia_src_path)/gpu/GrYUVProvider.h',
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define GrTypesPriv_DEFINED
|
||||
|
||||
#include "GrTypes.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
/**
|
||||
@ -419,6 +420,32 @@ enum GrIOType {
|
||||
kRW_GrIOType
|
||||
};
|
||||
|
||||
struct GrScissorState {
|
||||
GrScissorState() : fEnabled(false) {}
|
||||
GrScissorState(const SkIRect& rect) : fEnabled(true), fRect(rect) {}
|
||||
void setDisabled() { fEnabled = false; }
|
||||
void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
|
||||
bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& rect) {
|
||||
if (!fEnabled) {
|
||||
this->set(rect);
|
||||
return true;
|
||||
}
|
||||
return fRect.intersect(rect);
|
||||
}
|
||||
bool operator==(const GrScissorState& other) const {
|
||||
return fEnabled == other.fEnabled &&
|
||||
(false == fEnabled || fRect == other.fRect);
|
||||
}
|
||||
bool operator!=(const GrScissorState& other) const { return !(*this == other); }
|
||||
|
||||
bool enabled() const { return fEnabled; }
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
|
||||
private:
|
||||
bool fEnabled;
|
||||
SkIRect fRect;
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates the type of data that a GPU buffer will be used for.
|
||||
*/
|
||||
|
@ -9,7 +9,6 @@
|
||||
#define GrSurfaceProxy_DEFINED
|
||||
|
||||
#include "GrGpuResource.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
class GrTextureProxy;
|
||||
class GrRenderTargetProxy;
|
||||
|
@ -8,8 +8,8 @@
|
||||
#ifndef GrAppliedClip_DEFINED
|
||||
#define GrAppliedClip_DEFINED
|
||||
|
||||
#include "GrScissorState.h"
|
||||
#include "GrWindowRectsState.h"
|
||||
#include "GrTypesPriv.h"
|
||||
#include "GrWindowRectangles.h"
|
||||
|
||||
class GrFragmentProcessor;
|
||||
|
||||
@ -25,7 +25,7 @@ public:
|
||||
}
|
||||
|
||||
const GrScissorState& scissorState() const { return fScissorState; }
|
||||
const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
|
||||
const GrWindowRectangles& windowRects() const { return fWindowRects; }
|
||||
GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP.get(); }
|
||||
bool hasStencilClip() const { return fHasStencilClip; }
|
||||
|
||||
@ -36,15 +36,12 @@ public:
|
||||
return fScissorState.intersect(irect) && fClippedDrawBounds.intersect(SkRect::Make(irect));
|
||||
}
|
||||
|
||||
void addWindowRectangles(const GrWindowRectsState& windowState) {
|
||||
SkASSERT(!fWindowRectsState.enabled());
|
||||
fWindowRectsState = windowState;
|
||||
}
|
||||
|
||||
void addWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
|
||||
GrWindowRectsState::Mode mode) {
|
||||
SkASSERT(!fWindowRectsState.enabled());
|
||||
fWindowRectsState.set(windows, origin, mode);
|
||||
/**
|
||||
* Adds an exclusive window rectangle to the clip. It is not currently supported to switch the
|
||||
* windows to inclusive mode.
|
||||
*/
|
||||
void addWindowRectangle(const SkIRect& window) {
|
||||
fWindowRects.addWindow(window);
|
||||
}
|
||||
|
||||
void addCoverageFP(sk_sp<GrFragmentProcessor> fp) {
|
||||
@ -65,7 +62,7 @@ public:
|
||||
|
||||
private:
|
||||
GrScissorState fScissorState;
|
||||
GrWindowRectsState fWindowRectsState;
|
||||
GrWindowRectangles fWindowRects;
|
||||
sk_sp<GrFragmentProcessor> fClipCoverageFP;
|
||||
bool fHasStencilClip;
|
||||
SkRect fClippedDrawBounds;
|
||||
|
@ -287,14 +287,11 @@ bool GrClipStackClip::apply(GrContext* context, GrDrawContext* drawContext, bool
|
||||
return false;
|
||||
}
|
||||
|
||||
GrRenderTarget* rt = drawContext->accessRenderTarget();
|
||||
|
||||
const SkScalar clipX = SkIntToScalar(fOrigin.x()),
|
||||
clipY = SkIntToScalar(fOrigin.y());
|
||||
|
||||
SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY);
|
||||
const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds,
|
||||
rt->renderTargetPriv().maxWindowRectangles());
|
||||
const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds);
|
||||
|
||||
if (reducedClip.hasIBounds() &&
|
||||
!GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) {
|
||||
@ -303,17 +300,29 @@ bool GrClipStackClip::apply(GrContext* context, GrDrawContext* drawContext, bool
|
||||
out->addScissor(scissorSpaceIBounds);
|
||||
}
|
||||
|
||||
if (!reducedClip.windowRectangles().empty()) {
|
||||
out->addWindowRectangles(reducedClip.windowRectangles(), fOrigin,
|
||||
GrWindowRectsState::Mode::kExclusive);
|
||||
}
|
||||
|
||||
if (reducedClip.elements().isEmpty()) {
|
||||
return InitialState::kAllIn == reducedClip.initialState();
|
||||
}
|
||||
|
||||
SkASSERT(reducedClip.hasIBounds());
|
||||
|
||||
// Attempt to implement difference clip rects with window rectangles. This will eventually
|
||||
// become more comprehensive.
|
||||
if (drawContext->accessRenderTarget()->renderTargetPriv().supportsWindowRectangles() &&
|
||||
1 == reducedClip.elements().count() && !reducedClip.requiresAA() &&
|
||||
InitialState::kAllIn == reducedClip.initialState()) {
|
||||
const Element* element = reducedClip.elements().head();
|
||||
SkRegion::Op op = element->getOp();
|
||||
if (Element::kRect_Type == element->getType() &&
|
||||
(SkRegion::kDifference_Op == op || SkRegion::kXOR_Op == op)) {
|
||||
SkIRect window;
|
||||
element->getRect().round(&window);
|
||||
window.offset(-fOrigin);
|
||||
out->addWindowRectangle(window);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// An element count of 4 was chosen because of the common pattern in Blink of:
|
||||
// isect RR
|
||||
// diff RR
|
||||
@ -368,15 +377,12 @@ bool GrClipStackClip::apply(GrContext* context, GrDrawContext* drawContext, bool
|
||||
// use the stencil clip if we can't represent the clip as a rectangle.
|
||||
// TODO: these need to be swapped over to using a StencilAttachmentProxy
|
||||
GrStencilAttachment* stencilAttachment =
|
||||
context->resourceProvider()->attachStencilAttachment(rt);
|
||||
context->resourceProvider()->attachStencilAttachment(drawContext->accessRenderTarget());
|
||||
if (nullptr == stencilAttachment) {
|
||||
SkDebugf("WARNING: failed to attach stencil buffer for clip mask. Clip will be ignored.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// This relies on the property that a reduced sub-rect of the last clip will contain all the
|
||||
// relevant window rectangles that were in the last clip. This subtle requirement will go away
|
||||
// after clipping is overhauled.
|
||||
if (stencilAttachment->mustRenderClip(reducedClip.elementsGenID(), reducedClip.ibounds(),
|
||||
fOrigin)) {
|
||||
reducedClip.drawStencilClipMask(context, drawContext, fOrigin);
|
||||
|
@ -215,12 +215,9 @@ void GrDrawContextPriv::clear(const GrFixedClip& clip,
|
||||
void GrDrawContext::internalClear(const GrFixedClip& clip,
|
||||
const GrColor color,
|
||||
bool canIgnoreClip) {
|
||||
bool isFull = false;
|
||||
if (!clip.hasWindowRectangles()) {
|
||||
isFull = !clip.scissorEnabled() ||
|
||||
(canIgnoreClip && fContext->caps()->fullClearIsFree()) ||
|
||||
clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
|
||||
}
|
||||
bool isFull = !clip.scissorEnabled() ||
|
||||
(canIgnoreClip && fContext->caps()->fullClearIsFree()) ||
|
||||
clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
|
||||
|
||||
if (fContext->caps()->useDrawInsteadOfClear()) {
|
||||
// This works around a driver bug with clear by drawing a rect instead.
|
||||
|
@ -381,7 +381,7 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
|
||||
sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
|
||||
pipelineBuilder.numCoverageFragmentProcessors());
|
||||
args.fScissor = &appliedClip.scissorState();
|
||||
args.fWindowRectsState = &appliedClip.windowRectsState();
|
||||
args.fWindowRects = &appliedClip.windowRects();
|
||||
args.fHasStencilClip = appliedClip.hasStencilClip();
|
||||
if (!this->setupDstReadIfNecessary(pipelineBuilder, drawContext->accessRenderTarget(),
|
||||
clip, args.fOpts,
|
||||
|
@ -10,45 +10,25 @@
|
||||
#include "GrAppliedClip.h"
|
||||
#include "GrDrawContext.h"
|
||||
|
||||
bool GrFixedClip::quickContains(const SkRect& rect) const {
|
||||
if (fWindowRectsState.enabled()) {
|
||||
return false;
|
||||
}
|
||||
return !fScissorState.enabled() || GrClip::IsInsideClip(fScissorState.rect(), rect);
|
||||
}
|
||||
|
||||
void GrFixedClip::getConservativeBounds(int w, int h, SkIRect* devResult, bool* iior) const {
|
||||
devResult->setXYWH(0, 0, w, h);
|
||||
void GrFixedClip::getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||
bool* isIntersectionOfRects) const {
|
||||
devResult->setXYWH(0, 0, width, height);
|
||||
if (fScissorState.enabled()) {
|
||||
if (!devResult->intersect(fScissorState.rect())) {
|
||||
devResult->setEmpty();
|
||||
}
|
||||
}
|
||||
if (iior) {
|
||||
*iior = true;
|
||||
if (isIntersectionOfRects) {
|
||||
*isIntersectionOfRects = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GrFixedClip::isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const {
|
||||
if (fWindowRectsState.enabled()) {
|
||||
return false;
|
||||
}
|
||||
bool GrFixedClip::apply(GrContext*, GrDrawContext* drawContext, bool isHWAntiAlias,
|
||||
bool hasUserStencilSettings, GrAppliedClip* out) const {
|
||||
if (fScissorState.enabled()) {
|
||||
SkRect rect = SkRect::Make(fScissorState.rect());
|
||||
if (!rect.intersects(rtBounds)) {
|
||||
return false;
|
||||
}
|
||||
rr->setRect(rect);
|
||||
*aa = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool GrFixedClip::apply(GrContext*, GrDrawContext* dc, bool, bool, GrAppliedClip* out) const {
|
||||
if (fScissorState.enabled()) {
|
||||
SkIRect tightScissor = SkIRect::MakeWH(dc->width(), dc->height());
|
||||
if (!tightScissor.intersect(fScissorState.rect())) {
|
||||
SkIRect tightScissor;
|
||||
if (!tightScissor.intersect(fScissorState.rect(),
|
||||
SkIRect::MakeWH(drawContext->width(), drawContext->height()))) {
|
||||
return false;
|
||||
}
|
||||
if (IsOutsideClip(tightScissor, out->clippedDrawBounds())) {
|
||||
@ -59,10 +39,6 @@ bool GrFixedClip::apply(GrContext*, GrDrawContext* dc, bool, bool, GrAppliedClip
|
||||
}
|
||||
}
|
||||
|
||||
if (fWindowRectsState.enabled()) {
|
||||
out->addWindowRectangles(fWindowRectsState);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,7 @@
|
||||
#define GrFixedClip_DEFINED
|
||||
|
||||
#include "GrClip.h"
|
||||
#include "GrScissorState.h"
|
||||
#include "GrWindowRectsState.h"
|
||||
#include "GrTypesPriv.h"
|
||||
|
||||
/**
|
||||
* GrFixedClip is a clip that gets implemented by fixed-function hardware.
|
||||
@ -30,26 +29,32 @@ public:
|
||||
return fScissorState.intersect(irect);
|
||||
}
|
||||
|
||||
const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
|
||||
bool hasWindowRectangles() const { return fWindowRectsState.enabled(); }
|
||||
|
||||
void disableWindowRectangles() { fWindowRectsState.setDisabled(); }
|
||||
|
||||
void setWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
|
||||
GrWindowRectsState::Mode mode) {
|
||||
fWindowRectsState.set(windows, origin, mode);
|
||||
bool quickContains(const SkRect& rect) const final {
|
||||
return !fScissorState.enabled() || GrClip::IsInsideClip(fScissorState.rect(), rect);
|
||||
}
|
||||
void getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||
bool* isIntersectionOfRects) const final;
|
||||
|
||||
bool quickContains(const SkRect&) const override;
|
||||
void getConservativeBounds(int w, int h, SkIRect* devResult, bool* iior) const override;
|
||||
bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override;
|
||||
bool apply(GrContext*, GrDrawContext*, bool, bool, GrAppliedClip* out) const override;
|
||||
bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override {
|
||||
if (fScissorState.enabled()) {
|
||||
SkRect rect = SkRect::Make(fScissorState.rect());
|
||||
if (!rect.intersects(rtBounds)) {
|
||||
return false;
|
||||
}
|
||||
rr->setRect(rect);
|
||||
*aa = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserStencilSettings,
|
||||
GrAppliedClip* out) const final;
|
||||
|
||||
static const GrFixedClip& Disabled();
|
||||
|
||||
private:
|
||||
GrScissorState fScissorState;
|
||||
GrWindowRectsState fWindowRectsState;
|
||||
GrScissorState fScissorState;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -27,7 +27,7 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
pipeline->fRenderTarget.reset(rt);
|
||||
SkASSERT(pipeline->fRenderTarget);
|
||||
pipeline->fScissorState = *args.fScissor;
|
||||
pipeline->fWindowRectsState = *args.fWindowRectsState;
|
||||
pipeline->fWindowRects = *args.fWindowRects;
|
||||
if (builder.hasUserStencilSettings() || args.fHasStencilClip) {
|
||||
const GrRenderTargetPriv& rtPriv = rt->renderTargetPriv();
|
||||
pipeline->fStencilSettings.reset(*builder.getUserStencil(), args.fHasStencilClip,
|
||||
@ -230,7 +230,7 @@ bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b,
|
||||
a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
|
||||
a.fNumColorProcessors != b.fNumColorProcessors ||
|
||||
a.fScissorState != b.fScissorState ||
|
||||
!a.fWindowRectsState.cheapEqualTo(b.fWindowRectsState) ||
|
||||
a.fWindowRects != b.fWindowRects ||
|
||||
a.fFlags != b.fFlags ||
|
||||
a.fStencilSettings != b.fStencilSettings ||
|
||||
a.fDrawFace != b.fDrawFace ||
|
||||
|
@ -16,9 +16,9 @@
|
||||
#include "GrPrimitiveProcessor.h"
|
||||
#include "GrProcOptInfo.h"
|
||||
#include "GrProgramDesc.h"
|
||||
#include "GrScissorState.h"
|
||||
#include "GrStencilSettings.h"
|
||||
#include "GrWindowRectsState.h"
|
||||
#include "GrTypesPriv.h"
|
||||
#include "GrWindowRectangles.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
@ -60,7 +60,7 @@ public:
|
||||
const GrCaps* fCaps;
|
||||
GrPipelineOptimizations fOpts;
|
||||
const GrScissorState* fScissor;
|
||||
const GrWindowRectsState* fWindowRectsState;
|
||||
const GrWindowRectangles* fWindowRects;
|
||||
bool fHasStencilClip;
|
||||
GrXferProcessor::DstTexture fDstTexture;
|
||||
};
|
||||
@ -154,7 +154,7 @@ public:
|
||||
|
||||
const GrScissorState& getScissorState() const { return fScissorState; }
|
||||
|
||||
const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
|
||||
const GrWindowRectangles& getWindowRectangles() const { return fWindowRects; }
|
||||
|
||||
bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
|
||||
bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
|
||||
@ -223,7 +223,7 @@ private:
|
||||
typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
|
||||
RenderTarget fRenderTarget;
|
||||
GrScissorState fScissorState;
|
||||
GrWindowRectsState fWindowRectsState;
|
||||
GrWindowRectangles fWindowRects;
|
||||
GrStencilSettings fStencilSettings;
|
||||
GrDrawFace fDrawFace;
|
||||
uint32_t fFlags;
|
||||
|
@ -28,8 +28,7 @@ typedef SkClipStack::Element Element;
|
||||
* based on later intersect operations, and perhaps remove intersect-rects. We could optionally
|
||||
* take a rect in case the caller knows a bound on what is to be drawn through this clip.
|
||||
*/
|
||||
GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds,
|
||||
int maxWindowRectangles) {
|
||||
GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds) {
|
||||
SkASSERT(!queryBounds.isEmpty());
|
||||
fHasIBounds = false;
|
||||
|
||||
@ -95,15 +94,10 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds
|
||||
|
||||
// Now that we have determined the bounds to use and filtered out the trivial cases, call the
|
||||
// helper that actually walks the stack.
|
||||
this->walkStack(stack, tighterQuery, maxWindowRectangles);
|
||||
|
||||
if (fWindowRects.count() < maxWindowRectangles) {
|
||||
this->addInteriorWindowRectangles(maxWindowRectangles);
|
||||
}
|
||||
this->walkStack(stack, tighterQuery);
|
||||
}
|
||||
|
||||
void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBounds,
|
||||
int maxWindowRectangles) {
|
||||
void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBounds) {
|
||||
// walk backwards until we get to:
|
||||
// a) the beginning
|
||||
// b) an operation that is known to make the bounds all inside/outside
|
||||
@ -162,10 +156,6 @@ void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBound
|
||||
skippable = true;
|
||||
} else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
||||
skippable = true;
|
||||
} else if (fWindowRects.count() < maxWindowRectangles && !embiggens &&
|
||||
!element->isAA() && Element::kRect_Type == element->getType()) {
|
||||
this->addWindowRectangle(element->getRect(), false);
|
||||
skippable = true;
|
||||
}
|
||||
}
|
||||
if (!skippable) {
|
||||
@ -430,85 +420,10 @@ void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBound
|
||||
fInitialState = static_cast<GrReducedClip::InitialState>(initialTriState);
|
||||
}
|
||||
|
||||
static bool element_is_pure_subtract(SkRegion::Op op) {
|
||||
SkASSERT(op >= 0);
|
||||
return op <= SkRegion::kIntersect_Op;
|
||||
|
||||
GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
|
||||
GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
|
||||
}
|
||||
|
||||
void GrReducedClip::addInteriorWindowRectangles(int maxWindowRectangles) {
|
||||
SkASSERT(fWindowRects.count() < maxWindowRectangles);
|
||||
// Walk backwards through the element list and add window rectangles to the interiors of
|
||||
// "difference" elements. Quit if we encounter an element that may grow the clip.
|
||||
ElementList::Iter iter(fElements, ElementList::Iter::kTail_IterStart);
|
||||
for (; iter.get() && element_is_pure_subtract(iter.get()->getOp()); iter.prev()) {
|
||||
const Element* element = iter.get();
|
||||
if (SkRegion::kDifference_Op != element->getOp()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Element::kRect_Type == element->getType()) {
|
||||
SkASSERT(element->isAA());
|
||||
this->addWindowRectangle(element->getRect(), true);
|
||||
if (fWindowRects.count() >= maxWindowRectangles) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Element::kRRect_Type == element->getType()) {
|
||||
// For round rects we add two overlapping windows in the shape of a plus.
|
||||
const SkRRect& clipRRect = element->getRRect();
|
||||
SkVector insetTL = clipRRect.radii(SkRRect::kUpperLeft_Corner);
|
||||
SkVector insetBR = clipRRect.radii(SkRRect::kLowerRight_Corner);
|
||||
if (SkRRect::kComplex_Type == clipRRect.getType()) {
|
||||
const SkVector& insetTR = clipRRect.radii(SkRRect::kUpperRight_Corner);
|
||||
const SkVector& insetBL = clipRRect.radii(SkRRect::kLowerLeft_Corner);
|
||||
insetTL.fX = SkTMax(insetTL.x(), insetBL.x());
|
||||
insetTL.fY = SkTMax(insetTL.y(), insetTR.y());
|
||||
insetBR.fX = SkTMax(insetBR.x(), insetTR.x());
|
||||
insetBR.fY = SkTMax(insetBR.y(), insetBL.y());
|
||||
}
|
||||
const SkRect& bounds = clipRRect.getBounds();
|
||||
if (insetTL.x() + insetBR.x() >= bounds.width() ||
|
||||
insetTL.y() + insetBR.y() >= bounds.height()) {
|
||||
continue; // The interior "plus" is empty.
|
||||
}
|
||||
|
||||
SkRect horzRect = SkRect::MakeLTRB(bounds.left(), bounds.top() + insetTL.y(),
|
||||
bounds.right(), bounds.bottom() - insetBR.y());
|
||||
this->addWindowRectangle(horzRect, element->isAA());
|
||||
if (fWindowRects.count() >= maxWindowRectangles) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkRect vertRect = SkRect::MakeLTRB(bounds.left() + insetTL.x(), bounds.top(),
|
||||
bounds.right() - insetBR.x(), bounds.bottom());
|
||||
this->addWindowRectangle(vertRect, element->isAA());
|
||||
if (fWindowRects.count() >= maxWindowRectangles) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void GrReducedClip::addWindowRectangle(const SkRect& elementInteriorRect, bool elementIsAA) {
|
||||
SkIRect* window = &fWindowRects.addWindow();
|
||||
if (!elementIsAA) {
|
||||
elementInteriorRect.round(window);
|
||||
} else {
|
||||
elementInteriorRect.roundIn(window);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool GrReducedClip::intersectIBounds(const SkIRect& irect) {
|
||||
SkASSERT(fHasIBounds);
|
||||
if (!fIBounds.intersect(irect)) {
|
||||
fHasIBounds = false;
|
||||
fWindowRects.reset();
|
||||
fElements.reset();
|
||||
fRequiresAA = false;
|
||||
fInitialState = InitialState::kAllOut;
|
||||
@ -588,11 +503,6 @@ bool GrReducedClip::drawAlphaClipMask(GrDrawContext* dc) const {
|
||||
// we populate with a rasterization of the clip.
|
||||
GrFixedClip clip(SkIRect::MakeWH(fIBounds.width(), fIBounds.height()));
|
||||
|
||||
if (!fWindowRects.empty()) {
|
||||
clip.setWindowRectangles(fWindowRects, {fIBounds.left(), fIBounds.top()},
|
||||
GrWindowRectsState::Mode::kExclusive);
|
||||
}
|
||||
|
||||
// The scratch texture that we are drawing into can be substantially larger than the mask. Only
|
||||
// clear the part that we care about.
|
||||
GrColor initialCoverage = InitialState::kAllIn == this->initialState() ? -1 : 0;
|
||||
@ -660,23 +570,18 @@ public:
|
||||
StencilClip(const SkIRect& scissorRect) : fFixedClip(scissorRect) {}
|
||||
const GrFixedClip& fixedClip() const { return fFixedClip; }
|
||||
|
||||
void setWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
|
||||
GrWindowRectsState::Mode mode) {
|
||||
fFixedClip.setWindowRectangles(windows, origin, mode);
|
||||
}
|
||||
|
||||
private:
|
||||
bool quickContains(const SkRect&) const override {
|
||||
bool quickContains(const SkRect&) const final {
|
||||
return false;
|
||||
}
|
||||
void getConservativeBounds(int width, int height, SkIRect* bounds, bool* iior) const override {
|
||||
fFixedClip.getConservativeBounds(width, height, bounds, iior);
|
||||
void getConservativeBounds(int width, int height, SkIRect* devResult, bool* iior) const final {
|
||||
fFixedClip.getConservativeBounds(width, height, devResult, iior);
|
||||
}
|
||||
bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override {
|
||||
bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const final {
|
||||
return false;
|
||||
}
|
||||
bool apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA,
|
||||
bool hasUserStencilSettings, GrAppliedClip* out) const override {
|
||||
bool hasUserStencilSettings, GrAppliedClip* out) const final {
|
||||
if (!fFixedClip.apply(context, drawContext, useHWAA, hasUserStencilSettings, out)) {
|
||||
return false;
|
||||
}
|
||||
@ -695,11 +600,6 @@ bool GrReducedClip::drawStencilClipMask(GrContext* context,
|
||||
// We set the current clip to the bounds so that our recursive draws are scissored to them.
|
||||
StencilClip stencilClip(fIBounds.makeOffset(-clipOrigin.x(), -clipOrigin.y()));
|
||||
|
||||
if (!fWindowRects.empty()) {
|
||||
stencilClip.setWindowRectangles(fWindowRects, clipOrigin,
|
||||
GrWindowRectsState::Mode::kExclusive);
|
||||
}
|
||||
|
||||
bool initialState = InitialState::kAllIn == this->initialState();
|
||||
drawContext->drawContextPriv().clearStencilClip(stencilClip.fixedClip(), initialState);
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#ifndef GrReducedClip_DEFINED
|
||||
#define GrReducedClip_DEFINED
|
||||
|
||||
#include "GrWindowRectangles.h"
|
||||
#include "SkClipStack.h"
|
||||
#include "SkTLList.h"
|
||||
|
||||
@ -21,11 +20,11 @@ class GrDrawContext;
|
||||
*/
|
||||
class SK_API GrReducedClip {
|
||||
public:
|
||||
GrReducedClip(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles = 0);
|
||||
GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds);
|
||||
|
||||
/**
|
||||
* If hasIBounds() is true, this is the bounding box within which the clip elements are valid.
|
||||
* The caller must not modify any pixels outside this box. Undefined if hasIBounds() is false.
|
||||
* If hasIBounds() is true, this is the bounding box within which the reduced clip is valid, and
|
||||
* the caller must not modify any pixels outside this box. Undefined if hasIBounds() is false.
|
||||
*/
|
||||
const SkIRect& ibounds() const { SkASSERT(fHasIBounds); return fIBounds; }
|
||||
int left() const { return this->ibounds().left(); }
|
||||
@ -39,16 +38,10 @@ public:
|
||||
*/
|
||||
bool hasIBounds() const { return fHasIBounds; }
|
||||
|
||||
/**
|
||||
* If nonempty, this is a set of "exclusive" windows within which the clip elements are NOT
|
||||
* valid. The caller must not modify any pixels inside these windows.
|
||||
*/
|
||||
const GrWindowRectangles& windowRectangles() const { return fWindowRects; }
|
||||
|
||||
typedef SkTLList<SkClipStack::Element, 16> ElementList;
|
||||
|
||||
/**
|
||||
* Populated with a minimal list of elements required to fully implement the clip.
|
||||
* Populated with a minimal list of elements that implement the clip.
|
||||
*/
|
||||
const ElementList& elements() const { return fElements; }
|
||||
|
||||
@ -74,18 +67,15 @@ public:
|
||||
bool drawStencilClipMask(GrContext*, GrDrawContext*, const SkIPoint& clipOrigin) const;
|
||||
|
||||
private:
|
||||
void walkStack(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles);
|
||||
void addInteriorWindowRectangles(int maxWindowRectangles);
|
||||
void addWindowRectangle(const SkRect& elementInteriorRect, bool elementIsAA);
|
||||
void walkStack(const SkClipStack&, const SkRect& queryBounds);
|
||||
bool intersectIBounds(const SkIRect&);
|
||||
|
||||
SkIRect fIBounds;
|
||||
bool fHasIBounds;
|
||||
GrWindowRectangles fWindowRects;
|
||||
ElementList fElements;
|
||||
int32_t fElementsGenID;
|
||||
bool fRequiresAA;
|
||||
InitialState fInitialState;
|
||||
SkIRect fIBounds;
|
||||
bool fHasIBounds;
|
||||
ElementList fElements;
|
||||
int32_t fElementsGenID;
|
||||
bool fRequiresAA;
|
||||
InitialState fInitialState;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -127,8 +127,3 @@ const GrGpu::MultisampleSpecs&
|
||||
GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const {
|
||||
return fRenderTarget->getGpu()->getMultisampleSpecs(fRenderTarget, stencil);
|
||||
}
|
||||
|
||||
int GrRenderTargetPriv::maxWindowRectangles() const {
|
||||
return (this->flags() & Flags::kWindowRectsSupport) ?
|
||||
fRenderTarget->getGpu()->caps()->maxWindowRectangles() : 0;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
typedef GrRenderTarget::Flags Flags;
|
||||
|
||||
Flags flags() const { return fRenderTarget->fFlags; }
|
||||
int maxWindowRectangles() const;
|
||||
bool supportsWindowRectangles() const { return this->flags() & Flags::kWindowRectsSupport; }
|
||||
|
||||
private:
|
||||
explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {}
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrScissorState_DEFINED
|
||||
#define GrScissorState_DEFINED
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
class GrScissorState {
|
||||
public:
|
||||
GrScissorState() : fEnabled(false) {}
|
||||
GrScissorState(const SkIRect& rect) : fEnabled(true), fRect(rect) {}
|
||||
void setDisabled() { fEnabled = false; }
|
||||
void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
|
||||
bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& rect) {
|
||||
if (!fEnabled) {
|
||||
this->set(rect);
|
||||
return true;
|
||||
}
|
||||
return fRect.intersect(rect);
|
||||
}
|
||||
bool operator==(const GrScissorState& other) const {
|
||||
return fEnabled == other.fEnabled &&
|
||||
(false == fEnabled || fRect == other.fRect);
|
||||
}
|
||||
bool operator!=(const GrScissorState& other) const { return !(*this == other); }
|
||||
|
||||
bool enabled() const { return fEnabled; }
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
|
||||
private:
|
||||
bool fEnabled;
|
||||
SkIRect fRect;
|
||||
};
|
||||
|
||||
#endif
|
@ -15,15 +15,21 @@ class GrWindowRectangles {
|
||||
public:
|
||||
constexpr static int kMaxWindows = 8;
|
||||
|
||||
GrWindowRectangles() : fCount(0) {}
|
||||
enum class Mode : bool {
|
||||
kExclusive,
|
||||
kInclusive
|
||||
};
|
||||
|
||||
GrWindowRectangles(Mode mode = Mode::kExclusive) : fMode(mode), fCount(0) {}
|
||||
GrWindowRectangles(const GrWindowRectangles& that) : fCount(0) { *this = that; }
|
||||
~GrWindowRectangles() { SkSafeUnref(this->rec()); }
|
||||
|
||||
bool empty() const { return !fCount; }
|
||||
Mode mode() const { return fMode; }
|
||||
int count() const { return fCount; }
|
||||
bool disabled() const { return Mode::kExclusive == fMode && !fCount; }
|
||||
const SkIRect* data() const;
|
||||
|
||||
void reset();
|
||||
void reset(Mode = Mode::kExclusive);
|
||||
GrWindowRectangles& operator=(const GrWindowRectangles&);
|
||||
|
||||
SkIRect& addWindow(const SkIRect& window) { return this->addWindow() = window; }
|
||||
@ -38,7 +44,8 @@ private:
|
||||
|
||||
const Rec* rec() const { return fCount <= kNumLocalWindows ? nullptr : fRec; }
|
||||
|
||||
int fCount;
|
||||
Mode fMode;
|
||||
uint8_t fCount;
|
||||
union {
|
||||
SkIRect fLocalWindows[kNumLocalWindows]; // If fCount <= kNumLocalWindows.
|
||||
Rec* fRec; // If fCount > kNumLocalWindows.
|
||||
@ -58,13 +65,15 @@ inline const SkIRect* GrWindowRectangles::data() const {
|
||||
return fCount <= kNumLocalWindows ? fLocalWindows : fRec->fData;
|
||||
}
|
||||
|
||||
inline void GrWindowRectangles::reset() {
|
||||
inline void GrWindowRectangles::reset(Mode mode) {
|
||||
SkSafeUnref(this->rec());
|
||||
fMode = mode;
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
inline GrWindowRectangles& GrWindowRectangles::operator=(const GrWindowRectangles& that) {
|
||||
SkSafeUnref(this->rec());
|
||||
fMode = that.fMode;
|
||||
fCount = that.fCount;
|
||||
if (fCount <= kNumLocalWindows) {
|
||||
memcpy(fLocalWindows, that.fLocalWindows, fCount * sizeof(SkIRect));
|
||||
@ -89,7 +98,7 @@ inline SkIRect& GrWindowRectangles::addWindow() {
|
||||
}
|
||||
|
||||
inline bool GrWindowRectangles::operator==(const GrWindowRectangles& that) const {
|
||||
if (fCount != that.fCount) {
|
||||
if (fMode != that.fMode || fCount != that.fCount) {
|
||||
return false;
|
||||
}
|
||||
if (fCount > kNumLocalWindows && fRec == that.fRec) {
|
||||
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrWindowRectsState_DEFINED
|
||||
#define GrWindowRectsState_DEFINED
|
||||
|
||||
#include "GrWindowRectangles.h"
|
||||
|
||||
class GrWindowRectsState {
|
||||
public:
|
||||
enum class Mode : bool {
|
||||
kExclusive,
|
||||
kInclusive
|
||||
};
|
||||
|
||||
GrWindowRectsState() : fMode(Mode::kExclusive) {}
|
||||
GrWindowRectsState(const GrWindowRectangles& windows, const SkIPoint& origin, Mode mode)
|
||||
: fMode(mode)
|
||||
, fOrigin(origin)
|
||||
, fWindows(windows) {
|
||||
}
|
||||
|
||||
bool enabled() const { return Mode::kInclusive == fMode || !fWindows.empty(); }
|
||||
Mode mode() const { return fMode; }
|
||||
const SkIPoint& origin() const { return fOrigin; }
|
||||
const GrWindowRectangles& windows() const { return fWindows; }
|
||||
int numWindows() const { return fWindows.count(); }
|
||||
|
||||
void setDisabled() {
|
||||
fMode = Mode::kExclusive;
|
||||
fWindows.reset();
|
||||
}
|
||||
|
||||
void set(const GrWindowRectangles& windows, const SkIPoint& origin, Mode mode) {
|
||||
fMode = mode;
|
||||
fOrigin = origin;
|
||||
fWindows = windows;
|
||||
}
|
||||
|
||||
bool cheapEqualTo(const GrWindowRectsState& that) const {
|
||||
if (fMode != that.fMode) {
|
||||
return false;
|
||||
}
|
||||
if (!fWindows.empty() && fOrigin != that.fOrigin) {
|
||||
return false;
|
||||
}
|
||||
return fWindows == that.fWindows;
|
||||
}
|
||||
|
||||
private:
|
||||
Mode fMode;
|
||||
SkIPoint fOrigin;
|
||||
GrWindowRectangles fWindows;
|
||||
};
|
||||
|
||||
#endif
|
@ -71,9 +71,6 @@ private:
|
||||
// same color.
|
||||
GrClearBatch* cb = t->cast<GrClearBatch>();
|
||||
SkASSERT(cb->fRenderTarget == fRenderTarget);
|
||||
if (!fClip.windowRectsState().cheapEqualTo(cb->fClip.windowRectsState())) {
|
||||
return false;
|
||||
}
|
||||
if (cb->contains(this)) {
|
||||
fClip = cb->fClip;
|
||||
this->replaceBounds(*t);
|
||||
|
@ -564,7 +564,7 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
|
||||
|
||||
if (resetBits & kView_GrGLBackendState) {
|
||||
fHWScissorSettings.invalidate();
|
||||
fHWWindowRectsState.invalidate();
|
||||
fHWWindowRects.invalidate();
|
||||
fHWViewport.invalidate();
|
||||
}
|
||||
|
||||
@ -1997,42 +1997,39 @@ void GrGLGpu::flushScissor(const GrScissorState& scissorState,
|
||||
this->disableScissor();
|
||||
}
|
||||
|
||||
void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
|
||||
const GrGLRenderTarget* rt) {
|
||||
typedef GrWindowRectsState::Mode Mode;
|
||||
SkASSERT(!windowState.enabled() || rt->renderFBOID()); // Window rects can't be used on-screen.
|
||||
SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles());
|
||||
void GrGLGpu::flushWindowRectangles(const GrWindowRectangles& windows, const GrGLRenderTarget* rt) {
|
||||
typedef GrWindowRectangles::Mode Mode;
|
||||
SkASSERT(windows.count() <= this->caps()->maxWindowRectangles());
|
||||
SkASSERT(windows.disabled() || rt->renderFBOID()); // Window rectangles can't be used on-screen.
|
||||
|
||||
if (!this->caps()->maxWindowRectangles() ||
|
||||
fHWWindowRectsState.knownEqualTo(rt->origin(), rt->getViewport(), windowState)) {
|
||||
fHWWindowRects.equal(rt->origin(), rt->getViewport(), windows)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is purely a workaround for a spurious warning generated by gcc. Otherwise the above
|
||||
// assert would be sufficient. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=5912
|
||||
int numWindows = SkTMin(windowState.numWindows(), int(GrWindowRectangles::kMaxWindows));
|
||||
SkASSERT(windowState.numWindows() == numWindows);
|
||||
int numWindows = SkTMin(windows.count(), int(GrWindowRectangles::kMaxWindows));
|
||||
SkASSERT(windows.count() == numWindows);
|
||||
|
||||
GrGLIRect glwindows[GrWindowRectangles::kMaxWindows];
|
||||
const SkIRect* skwindows = windowState.windows().data();
|
||||
int dx = -windowState.origin().x(), dy = -windowState.origin().y();
|
||||
const SkIRect* skwindows = windows.data();
|
||||
for (int i = 0; i < numWindows; ++i) {
|
||||
const SkIRect& skwindow = skwindows[i].makeOffset(dx, dy);
|
||||
glwindows[i].setRelativeTo(rt->getViewport(), skwindow, rt->origin());
|
||||
glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], rt->origin());
|
||||
}
|
||||
|
||||
GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
|
||||
GrGLenum glmode = (Mode::kExclusive == windows.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
|
||||
GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts()));
|
||||
|
||||
fHWWindowRectsState.set(rt->origin(), rt->getViewport(), windowState);
|
||||
fHWWindowRects.set(rt->origin(), rt->getViewport(), windows);
|
||||
}
|
||||
|
||||
void GrGLGpu::disableWindowRectangles() {
|
||||
if (!this->caps()->maxWindowRectangles() || fHWWindowRectsState.knownDisabled()) {
|
||||
if (!this->caps()->maxWindowRectangles() || fHWWindowRects.disabled()) {
|
||||
return;
|
||||
}
|
||||
GL_CALL(WindowRectangles(GR_GL_EXCLUSIVE, 0, nullptr));
|
||||
fHWWindowRectsState.setDisabled();
|
||||
fHWWindowRects.setDisabled();
|
||||
}
|
||||
|
||||
void GrGLGpu::flushMinSampleShading(float minSampleShading) {
|
||||
@ -2082,7 +2079,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
|
||||
this->flushStencil(pipeline.getStencil());
|
||||
this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
|
||||
this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT);
|
||||
this->flushWindowRectangles(pipeline.getWindowRectangles(), glRT);
|
||||
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStencil().isDisabled());
|
||||
|
||||
// This must come after textures are flushed because a texture may need
|
||||
@ -2210,7 +2207,7 @@ void GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrRenderTarget* targ
|
||||
|
||||
this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr);
|
||||
this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
|
||||
this->flushWindowRectangles(clip.windowRectsState(), glRT);
|
||||
this->disableWindowRectangles();
|
||||
|
||||
GrGLfloat r, g, b, a;
|
||||
static const GrGLfloat scale255 = 1.f / 255.f;
|
||||
@ -2274,7 +2271,7 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
|
||||
this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
|
||||
|
||||
this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
|
||||
this->flushWindowRectangles(clip.windowRectsState(), glRT);
|
||||
this->disableWindowRectangles();
|
||||
|
||||
GL_CALL(StencilMask((uint32_t) clipStencilMask));
|
||||
GL_CALL(ClearStencil(value));
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "GrGLVertexArray.h"
|
||||
#include "GrGpu.h"
|
||||
#include "GrTypes.h"
|
||||
#include "GrWindowRectsState.h"
|
||||
#include "GrXferProcessor.h"
|
||||
#include "SkTArray.h"
|
||||
#include "SkTypes.h"
|
||||
@ -315,7 +314,7 @@ private:
|
||||
// disables the scissor
|
||||
void disableScissor();
|
||||
|
||||
void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*);
|
||||
void flushWindowRectangles(const GrWindowRectangles&, const GrGLRenderTarget*);
|
||||
void disableWindowRectangles();
|
||||
|
||||
void initFSAASupport();
|
||||
@ -425,36 +424,39 @@ private:
|
||||
|
||||
class {
|
||||
public:
|
||||
bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
|
||||
void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
|
||||
bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
|
||||
void setDisabled() { fRTOrigin = kDefault_GrSurfaceOrigin, fWindowState.setDisabled(); }
|
||||
bool valid() const { return kInvalidOrigin != fOrigin; }
|
||||
void invalidate() { fOrigin = kInvalidOrigin; }
|
||||
|
||||
void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
|
||||
const GrWindowRectsState& windowState) {
|
||||
fRTOrigin = rtOrigin;
|
||||
fViewport = viewport;
|
||||
fWindowState = windowState;
|
||||
bool disabled() const {
|
||||
return this->valid() && Mode::kExclusive == fWindows.mode() && !fWindows.count();
|
||||
}
|
||||
void setDisabled() { fOrigin = kDefault_GrSurfaceOrigin, fWindows.reset(); }
|
||||
|
||||
bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
|
||||
const GrWindowRectsState& windowState) const {
|
||||
bool equal(GrSurfaceOrigin org, const GrGLIRect& viewp,
|
||||
const GrWindowRectangles& windows) const {
|
||||
if (!this->valid()) {
|
||||
return false;
|
||||
}
|
||||
if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
|
||||
if (fWindows.count() && (fOrigin != org || fViewport != viewp)) {
|
||||
return false;
|
||||
}
|
||||
return fWindowState.cheapEqualTo(windowState);
|
||||
return fWindows == windows;
|
||||
}
|
||||
|
||||
void set(GrSurfaceOrigin org, const GrGLIRect& viewp, const GrWindowRectangles& windows) {
|
||||
fOrigin = org;
|
||||
fViewport = viewp;
|
||||
fWindows = windows;
|
||||
}
|
||||
|
||||
private:
|
||||
enum { kInvalidSurfaceOrigin = -1 };
|
||||
typedef GrWindowRectangles::Mode Mode;
|
||||
enum { kInvalidOrigin = -1 };
|
||||
|
||||
int fRTOrigin;
|
||||
int fOrigin;
|
||||
GrGLIRect fViewport;
|
||||
GrWindowRectsState fWindowState;
|
||||
} fHWWindowRectsState;
|
||||
GrWindowRectangles fWindows;
|
||||
} fHWWindowRects;
|
||||
|
||||
GrGLIRect fHWViewport;
|
||||
|
||||
|
@ -162,7 +162,6 @@ void GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* target,
|
||||
const GrFixedClip& clip,
|
||||
bool insideStencilMask) {
|
||||
SkASSERT(target);
|
||||
SkASSERT(!clip.hasWindowRectangles());
|
||||
|
||||
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(target);
|
||||
GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
|
||||
@ -216,7 +215,6 @@ void GrVkGpuCommandBuffer::onClearStencilClip(GrRenderTarget* target,
|
||||
void GrVkGpuCommandBuffer::onClear(GrRenderTarget* target, const GrFixedClip& clip, GrColor color) {
|
||||
// parent class should never let us get here with no RT
|
||||
SkASSERT(target);
|
||||
SkASSERT(!clip.hasWindowRectangles());
|
||||
|
||||
VkClearColorValue vkColor;
|
||||
GrColorToRGBAFloat(color, vkColor.float32);
|
||||
|
@ -162,8 +162,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
|
||||
GrGpu* gpu = ctxInfo.grContext()->getGpu();
|
||||
sk_sp<GrRenderTarget> defaultFBO(
|
||||
gpu->wrapBackendRenderTarget(backendDesc, kBorrow_GrWrapOwnership));
|
||||
REPORTER_ASSERT(reporter,
|
||||
!defaultFBO->renderTargetPriv().maxWindowRectangles());
|
||||
SkASSERT(!defaultFBO->renderTargetPriv().supportsWindowRectangles());
|
||||
|
||||
sk_sp<GrRenderTargetProxy> rtProxy(
|
||||
GrRenderTargetProxy::Make(caps, defaultFBO));
|
||||
@ -179,9 +178,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
tex.reset(provider->createTexture(desc, budgeted));
|
||||
sk_sp<GrRenderTarget> rt(sk_ref_sp(tex->asRenderTarget()));
|
||||
REPORTER_ASSERT(reporter,
|
||||
caps.maxWindowRectangles() ==
|
||||
rt->renderTargetPriv().maxWindowRectangles());
|
||||
SkASSERT(caps.maxWindowRectangles() <= 0 ||
|
||||
rt->renderTargetPriv().supportsWindowRectangles());
|
||||
|
||||
sk_sp<GrRenderTargetProxy> rtProxy(GrRenderTargetProxy::Make(caps, rt));
|
||||
check_surface(reporter, rtProxy.get(), origin,
|
||||
|
@ -31,6 +31,7 @@ DEF_TEST(WindowRectangles, reporter) {
|
||||
|
||||
GrWindowRectangles wr2(wr);
|
||||
REPORTER_ASSERT(reporter, wr2 == wr);
|
||||
REPORTER_ASSERT(reporter, wr2.mode() == wr.mode());
|
||||
REPORTER_ASSERT(reporter, wr2.count() == wr.count());
|
||||
REPORTER_ASSERT(reporter, !memcmp(wr2.data(), wr.data(), i * sizeof(SkIRect)));
|
||||
|
||||
@ -71,6 +72,21 @@ DEF_TEST(WindowRectangles, reporter) {
|
||||
REPORTER_ASSERT(reporter, !memcmp(A.data(), windowData,
|
||||
GrWindowRectangles::kMaxWindows * sizeof(SkIRect)));
|
||||
}
|
||||
|
||||
GrWindowRectangles wrI(GrWindowRectangles::Mode::kInclusive);
|
||||
for (int i = 0; i < wr.count(); ++i) {
|
||||
wrI.addWindow(windowData[i]);
|
||||
}
|
||||
REPORTER_ASSERT(reporter, wrI != wr);
|
||||
REPORTER_ASSERT(reporter, wrI.mode() != wr.mode());
|
||||
REPORTER_ASSERT(reporter, wrI.count() == wr.count());
|
||||
REPORTER_ASSERT(reporter, !memcmp(wrI.data(), wr.data(), wr.count() * sizeof(SkIRect)));
|
||||
|
||||
wr.reset(GrWindowRectangles::Mode::kInclusive);
|
||||
for (int i = 0; i < wrI.count(); ++i) {
|
||||
wr.addWindow(windowData[i]);
|
||||
}
|
||||
REPORTER_ASSERT(reporter, wrI == wr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user