+++ /dev/null
-/*
- * 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 "SkPath.h"
-#include "SkRandom.h"
-#include "SkRRect.h"
-#include "SkSurface.h"
-
-namespace skiagm {
-
-constexpr SkRect kSrcImageClip{75, 75, 275, 275};
-
-/*
- * The purpose of this test is to exercise all three codepaths in GrDrawContext (drawFilledRect,
- * fillRectToRect, fillRectWithLocalMatrix) that pre-crop filled rects based on the clip.
- *
- * The test creates an image of a green square surrounded by red background, then draws this image
- * in various ways with the red clipped out. The test is successful if there is no visible red
- * background, scissor is never used, and ideally, all the rectangles draw in one batch.
- */
-class CroppedRectsGM : public GM {
-private:
- SkString onShortName() override final { return SkString("croppedrects"); }
- SkISize onISize() override { return SkISize::Make(500, 500); }
-
- void onOnceBeforeDraw() override {
- sk_sp<SkSurface> srcSurface = SkSurface::MakeRasterN32Premul(500, 500);
- SkCanvas* srcCanvas = srcSurface->getCanvas();
-
- srcCanvas->clear(SK_ColorRED);
-
- SkPaint paint;
- paint.setColor(0xff00ff00);
- srcCanvas->drawRect(kSrcImageClip, paint);
-
- constexpr SkScalar kStrokeWidth = 10;
- SkPaint stroke;
- stroke.setStyle(SkPaint::kStroke_Style);
- stroke.setStrokeWidth(kStrokeWidth);
- stroke.setColor(0xff008800);
- srcCanvas->drawRect(kSrcImageClip.makeInset(kStrokeWidth / 2, kStrokeWidth / 2), stroke);
-
- fSrcImage = srcSurface->makeImageSnapshot(SkBudgeted::kYes, SkSurface::kNo_ForceUnique);
- fSrcImageShader = fSrcImage->makeShader(SkShader::kClamp_TileMode,
- SkShader::kClamp_TileMode);
- }
-
- void onDraw(SkCanvas* canvas) override {
- canvas->clear(SK_ColorWHITE);
-
- {
- // GrDrawContext::drawFilledRect.
- SkAutoCanvasRestore acr(canvas, true);
- SkPaint paint;
- paint.setShader(fSrcImageShader);
- paint.setFilterQuality(kNone_SkFilterQuality);
- canvas->clipRect(kSrcImageClip);
- canvas->drawPaint(paint);
- }
-
- {
- // GrDrawContext::fillRectToRect.
- SkAutoCanvasRestore acr(canvas, true);
- SkPaint paint;
- paint.setFilterQuality(kNone_SkFilterQuality);
- SkRect drawRect = SkRect::MakeXYWH(350, 100, 100, 300);
- canvas->clipRect(drawRect);
- canvas->drawImageRect(fSrcImage.get(),
- kSrcImageClip.makeOutset(0.5f * kSrcImageClip.width(),
- kSrcImageClip.height()),
- drawRect.makeOutset(0.5f * drawRect.width(), drawRect.height()),
- &paint);
- }
-
- {
- // GrDrawContext::fillRectWithLocalMatrix.
- SkAutoCanvasRestore acr(canvas, true);
- SkPath path;
- path.moveTo(kSrcImageClip.fLeft - kSrcImageClip.width(), kSrcImageClip.centerY());
- path.lineTo(kSrcImageClip.fRight + 3 * kSrcImageClip.width(), kSrcImageClip.centerY());
- SkPaint paint;
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(2 * kSrcImageClip.height());
- paint.setShader(fSrcImageShader);
- paint.setFilterQuality(kNone_SkFilterQuality);
- canvas->translate(-90, 263);
- canvas->scale(300 / kSrcImageClip.width(), 100 / kSrcImageClip.height());
- canvas->clipRect(kSrcImageClip);
- canvas->drawPath(path, paint);
- }
-
- // TODO: assert the draw target only has one batch in the post-MDB world.
- }
-
- sk_sp<SkImage> fSrcImage;
- sk_sp<SkShader> fSrcImageShader;
-
- typedef GM INHERITED;
-};
-
-DEF_GM( return new CroppedRectsGM(); )
-
-}
}
}
-// Attempts to crop a rect and optional local rect to the clip boundaries.
-// Returns false if the draw can be skipped entirely.
-static bool crop_filled_rect(const GrRenderTarget* rt, const GrClip& clip,
- const SkMatrix& viewMatrix, SkRect* rect,
- SkRect* localRect = nullptr) {
- if (!viewMatrix.rectStaysRect()) {
- return true;
- }
-
- SkMatrix inverseViewMatrix;
- if (!viewMatrix.invert(&inverseViewMatrix)) {
- return false;
- }
-
- SkIRect clipDevBounds;
- SkRect clipBounds;
- SkASSERT(inverseViewMatrix.rectStaysRect());
-
- clip.getConservativeBounds(rt->width(), rt->height(), &clipDevBounds);
- inverseViewMatrix.mapRect(&clipBounds, SkRect::Make(clipDevBounds));
-
- if (localRect) {
- if (!rect->intersects(clipBounds)) {
- return false;
- }
- const SkScalar dx = localRect->width() / rect->width();
- const SkScalar dy = localRect->height() / rect->height();
- if (clipBounds.fLeft > rect->fLeft) {
- localRect->fLeft += (clipBounds.fLeft - rect->fLeft) * dx;
- rect->fLeft = clipBounds.fLeft;
- }
- if (clipBounds.fTop > rect->fTop) {
- localRect->fTop += (clipBounds.fTop - rect->fTop) * dy;
- rect->fTop = clipBounds.fTop;
- }
- if (clipBounds.fRight < rect->fRight) {
- localRect->fRight -= (rect->fRight - clipBounds.fRight) * dx;
- rect->fRight = clipBounds.fRight;
- }
- if (clipBounds.fBottom < rect->fBottom) {
- localRect->fBottom -= (rect->fBottom - clipBounds.fBottom) * dy;
- rect->fBottom = clipBounds.fBottom;
- }
- return true;
- }
-
- return rect->intersect(clipBounds);
-}
-
bool GrDrawContext::drawFilledRect(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRect& rect,
const GrUserStencilSettings* ss) {
- SkRect croppedRect = rect;
- if (!crop_filled_rect(fRenderTarget.get(), clip, viewMatrix, &croppedRect)) {
- return true;
- }
SkAutoTUnref<GrDrawBatch> batch;
bool useHWAA;
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
- batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
+ batch.reset(ir->recordRect(rect, viewMatrix, paint.getColor(),
paint.isAntiAlias(), fInstancedPipelineInfo,
&useHWAA));
if (batch) {
// The fill path can handle rotation but not skew.
if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
SkRect devBoundRect;
- viewMatrix.mapRect(&devBoundRect, croppedRect);
+ viewMatrix.mapRect(&devBoundRect, rect);
batch.reset(GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix,
- croppedRect, devBoundRect));
+ rect, devBoundRect));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
if (ss) {
}
}
} else {
- this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, nullptr, ss);
+ this->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss);
return true;
}
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect");
- SkRect croppedRect = rectToDraw;
- SkRect croppedLocalRect = localRect;
- if (!crop_filled_rect(fRenderTarget.get(), clip, viewMatrix, &croppedRect, &croppedLocalRect)) {
- return;
- }
-
AutoCheckFlush acf(fDrawingManager);
SkAutoTUnref<GrDrawBatch> batch;
bool useHWAA;
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
- batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), croppedLocalRect,
+ batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localRect,
paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) &&
view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
- batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix,
- croppedRect, croppedLocalRect));
+ batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix, rectToDraw,
+ localRect));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
this->drawBatch(pipelineBuilder, clip, batch);
return;
}
} else {
- this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect,
+ this->drawNonAAFilledRect(clip, paint, viewMatrix, rectToDraw, &localRect,
nullptr, nullptr);
}
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatrix");
- SkRect croppedRect = rectToDraw;
- if (!crop_filled_rect(fRenderTarget.get(), clip, viewMatrix, &croppedRect)) {
- return;
- }
-
AutoCheckFlush acf(fDrawingManager);
SkAutoTUnref<GrDrawBatch> batch;
bool useHWAA;
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
- batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), localMatrix,
+ batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localMatrix,
paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) &&
view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix,
- croppedRect));
+ rectToDraw));
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
} else {
- this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr,
+ this->drawNonAAFilledRect(clip, paint, viewMatrix, rectToDraw, nullptr,
&localMatrix, nullptr);
}