Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Unified Diff: src/gpu/draws/GrDrawRect.cpp

Issue 1336413006: Just an experiment (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/draws/GrDrawRect.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/draws/GrDrawRect.cpp
diff --git a/src/gpu/draws/GrDrawRect.cpp b/src/gpu/draws/GrDrawRect.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..22b98208dd2aecfe2bcaed771c61f1014d050808
--- /dev/null
+++ b/src/gpu/draws/GrDrawRect.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrDrawRect.h"
+
+#include "GrContext.h"
+#include "GrClip.h"
+#include "GrDrawTarget.h"
+#include "GrRenderTarget.h"
+#include "GrStrokeInfo.h"
+#include "SkColorFilter.h"
+#include "SkImageFilter.h"
+#include "SkGr.h"
+#include "SkMatrix.h"
+#include "SkMaskFilter.h"
+#include "SkPaint.h"
+#include "SkRect.h"
+#include "SkShader.h"
+#include "SkXfermode.h"
+#include "batches/GrRectBatchFactory.h"
+
+enum RectBatchType {
+ kAAStroke_RectBatchType,
+ kAAFill_RectBatchType,
+ kNonAAFill_RectBatchType,
+ kNonAAStroke_RectBatchType,
+};
+
+class GrDrawRectSnap : public GrDrawSnap {
+public:
+ GrDrawRectSnap(const SkPaint& paint,
+ const GrClip& clip,
+ RectBatchType type,
+ bool snapToPixelCenter)
+ : fShader(SkSafeRef(paint.getShader()))
+ , fMaskFilter(SkSafeRef(paint.getMaskFilter()))
+ , fImageFilter(SkSafeRef(paint.getImageFilter()))
+ , fColorFilter(SkSafeRef(paint.getColorFilter()))
+ , fClipGenID(clip.clipType() != GrClip::kClipStack_ClipType ?
+ -1 :
+ clip.clipStack()->getTopmostGenID())
+ , fType(type)
+ , fSnapToPixelCenters(snapToPixelCenter)
+ , fIsDither(paint.isDither()) {
+ fClassID = GrDrawRect::ClassID();
+ }
+
+ bool canBatch(const SkPaint& paint,
+ const GrClip& clip,
+ RectBatchType type,
+ bool snapToPixelCenters) const {
+ return paint.getShader() == fShader &&
+ paint.getMaskFilter() == fMaskFilter &&
+ paint.getImageFilter() == fImageFilter &&
+ paint.getColorFilter() == fColorFilter &&
+ paint.isDither() == fIsDither &&
+ fClipGenID != -1 && clip.clipType() == GrClip::kClipStack_ClipType &&
+ fClipGenID == clip.clipStack()->getTopmostGenID() &&
+ fType == type &&
+ fSnapToPixelCenters == snapToPixelCenters;
+ }
+
+ // we only bother fast pathing kSrcOver_Mode, though we could do quite a bit more
+ static bool CanSnap(const SkPaint& paint) {
+ return SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
+ }
+
+private:
+ SkAutoTUnref<SkShader> fShader;
+ SkAutoTUnref<SkMaskFilter> fMaskFilter;
+ SkAutoTUnref<SkImageFilter> fImageFilter;
+ SkAutoTUnref<SkColorFilter> fColorFilter;
+ int32_t fClipGenID;
+ RectBatchType fType;
+ bool fSnapToPixelCenters;
+ bool fIsDither;
+
+ typedef GrDrawSnap INHERITED;
+};
+
+inline static RectBatchType compute_rect_batch_type(bool useAA, SkScalar width) {
+ if (useAA) {
+ if (width >= 0) {
+ return kAAStroke_RectBatchType;
+ } else {
+ return kAAFill_RectBatchType;
+ }
+ } else if (width >= 0) {
+ return kNonAAStroke_RectBatchType;
+ } else {
+ return kNonAAFill_RectBatchType;
+ }
+}
+
+inline static bool can_fastpath(GrDrawTarget* drawTarget,
+ const SkPaint& paint,
+ const GrClip& clip,
+ GrColor color,
+ const SkMatrix& viewMatrix,
+ const SkRect& rect,
+ const GrStrokeInfo& strokeInfo,
+ RectBatchType batchType,
+ bool snapToPixelCenters) {
+ GrBatch* lastBatch = drawTarget->lastBatch();
+ if (!lastBatch) {
+ return false;
+ }
+
+ const GrDrawSnap* lastSnap = lastBatch->drawSnap();
+ if (!lastSnap) {
+ return false;
+ }
+
+ if (lastSnap->classID() != GrDrawRect::ClassID()) {
+ return false;
+ }
+
+ const GrDrawRectSnap* lastSnapCast = static_cast<const GrDrawRectSnap*>(lastSnap);
+ if (lastSnapCast->canBatch(paint, clip, batchType, snapToPixelCenters)) {
+ switch (batchType) {
+ case kAAStroke_RectBatchType:
+ if (GrAAStrokeRectBatch::Append(lastBatch, color, viewMatrix, rect,
+ strokeInfo)) {
+ return true;
+ }
+ break;
+ case kAAFill_RectBatchType:
+ GrAAFillRectBatch::Append(lastBatch, color, viewMatrix, rect);
+ return true;
+ case kNonAAFill_RectBatchType:
+ if (GrNonAAFillRectBatch::Append(lastBatch, color, viewMatrix, rect,
+ nullptr, nullptr)) {
+ return true;
+ }
+ break;
+ case kNonAAStroke_RectBatchType:
+ // GrNonAAStrokeRectBatch doesn't batch yet
+ break;
+ }
+ }
+
+ return false;
+}
+
+void GrDrawRect::execute(GrDrawTarget* drawTarget) const {
+ const SkPaint& paint = *fPaint;
+ const GrClip& clip = *fClip;
+ const SkMatrix& viewMatrix = *fViewMatrix;
+ const SkRect& rect = *fRect;
+
+ SkScalar width = nullptr == fStrokeInfo ? -1 : fStrokeInfo->getWidth();
+
+ bool needAA = fPaint->isAntiAlias() && !fRenderTarget->isUnifiedMultisampled();
+
+ // The fill path can handle rotation but not skew
+ // The stroke path needs the rect to remain axis aligned (no rotation or skew)
+ // None of our AA draw rect calls can handle perspective yet
+ bool canApplyAA = width >= 0 ? viewMatrix.rectStaysRect() : viewMatrix.preservesRightAngles();
+ bool useAA = needAA && canApplyAA;
+
+ // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic
+ bool snapToPixelCenters = !useAA && (0 == width && !fRenderTarget->isUnifiedMultisampled());
+
+ // TODO we also do this on the paint, do we need to?
+ SkColor paintColor = paint.getColor();
+ if (fPaint->getColorFilter() && !paint.getShader()) {
+ paintColor = paint.getColorFilter()->filterColor(paintColor);
+ }
+ GrColor color = SkColor2GrColor(paintColor);
+
+ RectBatchType batchType = compute_rect_batch_type(useAA, width);
+ if (can_fastpath(drawTarget, *fPaint, clip, color, viewMatrix, rect, *fStrokeInfo, batchType,
+ snapToPixelCenters)) {
+ return;
+ }
+
+ SkAutoTUnref<GrDrawBatch> batch;
+ switch (batchType) {
+ case kAAStroke_RectBatchType:
+ batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, *fStrokeInfo));
+ break;
+ case kAAFill_RectBatchType:
+ batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect));
+ break;
+ case kNonAAFill_RectBatchType:
+ batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect, nullptr,
+ nullptr));
+ break;
+ case kNonAAStroke_RectBatchType:
+ batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect, width,
+ snapToPixelCenters));
+ break;
+ }
+
+ GrPaint grPaint;
+ if (!SkPaint2GrPaint(fContext, fRenderTarget, paint, viewMatrix, true, &grPaint)) {
+ return;
+ }
+
+ GrPipelineBuilder pipelineBuilder(grPaint, fRenderTarget, clip);
+
+ // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
+ // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA
+ // is enabled because it can cause ugly artifacts.
+ pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
+ snapToPixelCenters);
+ drawTarget->drawBatch(pipelineBuilder, batch);
+ if (GrDrawRectSnap::CanSnap(paint)) {
+ batch->setDrawSnap(new GrDrawRectSnap(paint, clip, batchType, snapToPixelCenters));
+ }
+}
« no previous file with comments | « src/gpu/draws/GrDrawRect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698