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

Unified Diff: src/gpu/SkGpuDevice_drawTexture.cpp

Issue 1424313010: Separate out natively-texture image/bmp draws from cached-as-texture image/bmp draws (Closed) Base URL: https://skia.googlesource.com/skia.git@const
Patch Set: update Created 5 years, 1 month 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/SkGpuDevice.cpp ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/SkGpuDevice_drawTexture.cpp
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..902aae0843d35f191e76d2765f962ccfa8564d22
--- /dev/null
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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 "SkGpuDevice.h"
+
+#include "GrBlurUtils.h"
+#include "GrCaps.h"
+#include "GrDrawContext.h"
+#include "GrStrokeInfo.h"
+#include "GrTextureParamsAdjuster.h"
+#include "SkDraw.h"
+#include "SkGrPriv.h"
+#include "SkMaskFilter.h"
+#include "effects/GrBicubicEffect.h"
+#include "effects/GrSimpleTextureEffect.h"
+#include "effects/GrTextureDomain.h"
+
+static inline bool use_shader(bool textureIsAlphaOnly, const SkPaint& paint) {
+ return textureIsAlphaOnly && paint.getShader();
+}
+
+/** Determines how to combine the texture FP with the paint's color and SkShader, if any. */
+static const GrFragmentProcessor* mix_texture_fp_with_paint_color_and_shader(
+ const GrFragmentProcessor* textureFP,
+ bool textureIsAlphaOnly,
+ GrContext* context,
+ const SkMatrix& viewMatrix,
+ const SkPaint& paint) {
+ // According to the SkCanvas API, we only consider the shader if the bitmap or image being
+ // rendered is alpha-only.
+ if (textureIsAlphaOnly) {
+ if (const SkShader* shader = paint.getShader()) {
+ SkAutoTUnref<const GrFragmentProcessor> shaderFP(
+ shader->asFragmentProcessor(context,
+ viewMatrix,
+ nullptr,
+ paint.getFilterQuality()));
+ if (!shaderFP) {
+ return nullptr;
+ }
+ const GrFragmentProcessor* fpSeries[] = { shaderFP, textureFP };
+ return GrFragmentProcessor::RunInSeries(fpSeries, 2);
+ } else {
+ return GrFragmentProcessor::MulOutputByInputUnpremulColor(textureFP);
+ }
+ } else {
+ return GrFragmentProcessor::MulOutputByInputAlpha(textureFP);
+ }
+}
+
+void SkGpuDevice::drawTextureAdjuster(GrTextureAdjuster* adjuster,
+ bool alphaOnly,
+ const SkRect* srcRect,
+ const SkRect* dstRect,
+ SkCanvas::SrcRectConstraint constraint,
+ const SkMatrix& viewMatrix,
+ const GrClip& clip,
+ const SkPaint& paint) {
+ // Figure out the actual dst and src rect by clipping the src rect to the bounds of the
+ // adjuster. If the src rect is clipped then the dst rect must be recomputed. Also determine
+ // the matrix that maps the src rect to the dst rect.
+ SkRect clippedSrcRect;
+ SkRect clippedDstRect;
+ SkIRect contentIBounds;
+ adjuster->getContentArea(&contentIBounds);
+ const SkRect contentBounds = SkRect::Make(contentIBounds);
+ SkMatrix srcToDstMatrix;
+ if (srcRect) {
+ if (!dstRect) {
+ dstRect = &contentBounds;
+ }
+ if (!contentBounds.contains(*srcRect)) {
+ clippedSrcRect = *srcRect;
+ if (!clippedSrcRect.intersect(contentBounds)) {
+ return;
+ }
+ if (!srcToDstMatrix.setRectToRect(*srcRect, *dstRect, SkMatrix::kFill_ScaleToFit)) {
+ return;
+ }
+ srcToDstMatrix.mapRect(&clippedDstRect, clippedSrcRect);
+ } else {
+ clippedSrcRect = *srcRect;
+ clippedDstRect = *dstRect;
+ if (!srcToDstMatrix.setRectToRect(*srcRect, *dstRect, SkMatrix::kFill_ScaleToFit)) {
+ return;
+ }
+ }
+ } else {
+ clippedSrcRect = contentBounds;
+ if (dstRect) {
+ clippedDstRect = *dstRect;
+ if (!srcToDstMatrix.setRectToRect(contentBounds, *dstRect,
+ SkMatrix::kFill_ScaleToFit)) {
+ return;
+ }
+ } else {
+ clippedDstRect = contentBounds;
+ srcToDstMatrix.reset();
+ }
+ }
+
+ this->drawTextureAdjusterImpl(adjuster, alphaOnly, clippedSrcRect, clippedDstRect, constraint,
+ viewMatrix, srcToDstMatrix, clip, paint);
+}
+
+void SkGpuDevice::drawTextureAdjusterImpl(GrTextureAdjuster* adjuster,
+ bool alphaTexture,
+ const SkRect& clippedSrcRect,
+ const SkRect& clippedDstRect,
+ SkCanvas::SrcRectConstraint constraint,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& srcToDstMatrix,
+ const GrClip& clip,
+ const SkPaint& paint) {
+ // Specifying the texture coords as local coordinates is an attempt to enable more batching
+ // by not baking anything about the srcRect, dstRect, or viewMatrix, into the texture FP. In
+ // the future this should be an opaque optimization enabled by the combination of batch/GP and
+ // FP.
+ const SkMatrix* textureFPMatrix;
+ SkMatrix tempMatrix;
+ const SkMaskFilter* mf = paint.getMaskFilter();
+ GrTexture* texture = adjuster->originalTexture();
+ // The shader expects proper local coords, so we can't replace local coords with texture coords
+ // if the shader will be used. If we have a mask filter we will change the underlying geometry
+ // that is rendered.
+ bool canUseTextureCoordsAsLocalCoords = !use_shader(alphaTexture, paint) && !mf;
+ if (canUseTextureCoordsAsLocalCoords) {
+ textureFPMatrix = &SkMatrix::I();
+ } else {
+ if (!srcToDstMatrix.invert(&tempMatrix)) {
+ return;
+ }
+ tempMatrix.postIDiv(texture->width(), texture->height());
+ textureFPMatrix = &tempMatrix;
+ }
+
+ bool doBicubic;
+ GrTextureParams::FilterMode fm =
+ GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix, srcToDstMatrix,
+ &doBicubic);
+ const GrTextureParams::FilterMode* filterMode = doBicubic ? nullptr : &fm;
+
+ GrTextureAdjuster::FilterConstraint constraintMode;
+ if (SkCanvas::kFast_SrcRectConstraint == constraint) {
+ constraintMode = GrTextureAdjuster::kNo_FilterConstraint;
+ } else {
+ constraintMode = GrTextureAdjuster::kYes_FilterConstraint;
+ }
+
+ // If we have to outset for AA then we will generate texture coords outside the src rect. The
+ // same happens for any mask filter that extends the bounds rendered in the dst.
+ // This is conservative as a mask filter does not have to expand the bounds rendered.
+ bool coordsAllInsideSrcRect = !paint.isAntiAlias() && !mf;
+
+ SkAutoTUnref<const GrFragmentProcessor> fp(adjuster->createFragmentProcessor(
+ *textureFPMatrix, clippedSrcRect, constraintMode, coordsAllInsideSrcRect, filterMode));
+ if (!fp) {
+ return;
+ }
+ fp.reset(mix_texture_fp_with_paint_color_and_shader(fp, alphaTexture, this->context(),
+ viewMatrix, paint));
+ GrPaint grPaint;
+ if (!SkPaintToGrPaintReplaceShader(fContext, paint, fp, &grPaint)) {
+ return;
+ }
+
+ if (canUseTextureCoordsAsLocalCoords) {
+ SkRect localRect;
+ localRect.fLeft = clippedSrcRect.fLeft / texture->width();
+ localRect.fBottom = clippedSrcRect.fBottom / texture->height();
+ localRect.fRight = clippedSrcRect.fRight / texture->width();
+ localRect.fTop = clippedSrcRect.fTop / texture->height();
+ fDrawContext->fillRectToRect(clip, grPaint, viewMatrix, clippedDstRect, localRect);
+ return;
+ }
+
+ if (!mf) {
+ fDrawContext->drawRect(clip, grPaint, viewMatrix, clippedDstRect);
+ return;
+ }
+
+ // First see if we can do the draw + mask filter direct to the dst.
+ SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
+ SkRRect rrect;
+ rrect.setRect(clippedDstRect);
+ if (mf->directFilterRRectMaskGPU(fContext->textureProvider(),
+ fDrawContext,
+ &grPaint,
+ clip,
+ viewMatrix,
+ rec,
+ rrect)) {
+ return;
+ }
+ SkPath rectPath;
+ rectPath.addRect(clippedDstRect);
+ GrBlurUtils::drawPathWithMaskFilter(this->context(), fDrawContext, fRenderTarget, fClip,
+ rectPath, &grPaint, viewMatrix, mf, paint.getPathEffect(),
+ GrStrokeInfo::FillInfo());
+}
« no previous file with comments | « src/gpu/SkGpuDevice.cpp ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698