From ceef4fb5c498003be77a32a46cedfbf5da22a274 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Fri, 18 Aug 2017 13:05:54 +0000 Subject: Revert "Add GrTextureOp and use to implement SkGpuDevice::drawImage[Rect]() when possible" This reverts commit 3fd295550f8c4fecd4bc61ce916738d49310eb67. Reason for revert: breaking things Original change's description: > Add GrTextureOp and use to implement SkGpuDevice::drawImage[Rect]() when possible > > This op draws a texture rectangle in src over blending with no edge antialiasing. It less powerful than NonAAFillRectOp/GrPaint but has less CPU overhead. > > Change-Id: Ia6107bb67c1c2a83de14c665aff64b0de2750fba > Reviewed-on: https://skia-review.googlesource.com/33802 > Commit-Queue: Brian Salomon > Reviewed-by: Robert Phillips TBR=djsollen@google.com,bsalomon@google.com,robertphillips@google.com,brianosman@google.com Change-Id: I9cdbeeac15b17d2d6b3385560ed826397c0373c6 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/36220 Reviewed-by: Brian Salomon Commit-Queue: Brian Salomon --- src/gpu/GrGpuResourceRef.h | 3 +- src/gpu/GrRenderTargetContext.cpp | 16 -- src/gpu/GrRenderTargetContext.h | 11 -- src/gpu/GrResourceProvider.cpp | 5 +- src/gpu/GrResourceProvider.h | 2 - src/gpu/SkGpuDevice.cpp | 91 +++++----- src/gpu/SkGpuDevice.h | 22 +-- src/gpu/SkGpuDevice_drawTexture.cpp | 98 +--------- src/gpu/ops/GrTextureOp.cpp | 345 ------------------------------------ src/gpu/ops/GrTextureOp.h | 28 --- 10 files changed, 56 insertions(+), 565 deletions(-) delete mode 100644 src/gpu/ops/GrTextureOp.cpp delete mode 100644 src/gpu/ops/GrTextureOp.h (limited to 'src/gpu') diff --git a/src/gpu/GrGpuResourceRef.h b/src/gpu/GrGpuResourceRef.h index 1d85d7df33..a56674b494 100644 --- a/src/gpu/GrGpuResourceRef.h +++ b/src/gpu/GrGpuResourceRef.h @@ -155,8 +155,7 @@ public: /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as pending on the resource when markPendingIO is called. */ - GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) {} - GrTGpuResourceRef(sk_sp resource, GrIOType ioType) : INHERITED(resource, ioType) {} + GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) { } T* get() const { return static_cast(this->getResource()); } diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 3f9dcbb0bd..39515adc0a 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -43,7 +43,6 @@ #include "ops/GrSemaphoreOp.h" #include "ops/GrShadowRRectOp.h" #include "ops/GrStencilPathOp.h" -#include "ops/GrTextureOp.h" #include "text/GrAtlasTextContext.h" #include "text/GrStencilAndCoverTextContext.h" @@ -770,21 +769,6 @@ void GrRenderTargetContext::fillRectToRect(const GrClip& clip, this->internalDrawPath(clip, std::move(paint), aa, viewAndUnLocalMatrix, path, GrStyle()); } -void GrRenderTargetContext::drawTextureAffine(const GrClip& clip, sk_sp proxy, - GrSamplerParams::FilterMode filter, GrColor color, - const SkRect& srcRect, const SkRect& dstRect, - const SkMatrix& viewMatrix, - sk_sp colorSpaceXform) { - ASSERT_SINGLE_OWNER - RETURN_IF_ABANDONED - SkDEBUGCODE(this->validate();) - GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawTextureAffine", fContext); - SkASSERT(!viewMatrix.hasPerspective()); - bool allowSRGB = SkToBool(this->getColorSpace()); - this->addDrawOp(clip, GrTextureOp::Make(std::move(proxy), filter, color, srcRect, dstRect, - viewMatrix, std::move(colorSpaceXform), allowSRGB)); -} - void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip, GrPaint&& paint, GrAA aa, diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 084e1530a4..a73f4c9f8f 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -134,17 +134,6 @@ public: const SkRect& rect, const SkMatrix& localMatrix); - /** - * Creates an op that draws a subrectangle of a texture. The passed color is modulated by the - * texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect' - * specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to - * device space. The edges of the rendered rectangle are not antialiased. This asserts that the - * view matrix does not have perspective. - */ - void drawTextureAffine(const GrClip& clip, sk_sp, GrSamplerParams::FilterMode, - GrColor, const SkRect& srcRect, const SkRect& dstRect, - const SkMatrix& viewMatrix, sk_sp); - /** * Draw a roundrect using a paint. * diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index 323139ea0a..1979570fe0 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -362,17 +362,14 @@ const GrBuffer* GrResourceProvider::createPatternedIndexBuffer(const uint16_t* p return buffer; } -static constexpr int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1; - const GrBuffer* GrResourceProvider::createQuadIndexBuffer() { + static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1; GR_STATIC_ASSERT(4 * kMaxQuads <= 65535); static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 }; return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey); } -int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; } - sk_sp GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) { SkASSERT(this->gpu()->pathRendering()); return this->gpu()->pathRendering()->createPath(path, style); diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h index 9616d7541d..28207b7a87 100644 --- a/src/gpu/GrResourceProvider.h +++ b/src/gpu/GrResourceProvider.h @@ -152,8 +152,6 @@ public: return this->createQuadIndexBuffer(); } - static int QuadCountOfQuadBuffer(); - /** * Factories for GrPath and GrPathRange objects. It's an error to call these if path rendering * is not supported. diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 0cf2ae5893..2d024b014b 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -6,6 +6,7 @@ */ #include "SkGpuDevice.h" + #include "GrBitmapTextureMaker.h" #include "GrBlurUtils.h" #include "GrContext.h" @@ -758,8 +759,10 @@ bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr const SkMatrix& viewMatrix, const SkMatrix& srcToDstRect) const { ASSERT_SINGLE_OWNER - // If image is explicitly texture backed then we shouldn't get here. - SkASSERT(!image->isTextureBacked()); + // if image is explictly texture backed then just use the texture + if (image->isTextureBacked()) { + return false; + } GrSamplerParams params; bool doBicubic; @@ -840,7 +843,7 @@ void SkGpuDevice::drawBitmap(const SkBitmap& bitmap, } GrBitmapTextureMaker maker(fContext.get(), bitmap); this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kStrict_SrcRectConstraint, - viewMatrix, paint); + viewMatrix, this->clip(), paint); } // This method outsets 'iRect' by 'outset' all around and then clamps its extents to @@ -1199,7 +1202,7 @@ void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap, } } GrBitmapTextureMaker maker(fContext.get(), bitmap); - this->drawTextureProducer(&maker, src, dst, constraint, this->ctm(), paint); + this->drawTextureProducer(&maker, src, dst, constraint, this->ctm(), this->clip(), paint); } sk_sp SkGpuDevice::makeSpecial(const SkBitmap& bitmap) { @@ -1286,50 +1289,52 @@ void SkGpuDevice::drawDevice(SkBaseDevice* device, this->drawSpecial(srcImg.get(), left, top, paint, nullptr, SkMatrix::I()); } -void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint& paint) { +void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y, + const SkPaint& paint) { ASSERT_SINGLE_OWNER SkMatrix viewMatrix = this->ctm(); viewMatrix.preTranslate(x, y); uint32_t pinnedUniqueID; + if (sk_sp proxy = as_IB(image)->refPinnedTextureProxy(&pinnedUniqueID)) { - this->drawPinnedTextureProxy(std::move(proxy), pinnedUniqueID, as_IB(image)->colorSpace(), - image->alphaType(), nullptr, nullptr, - SkCanvas::kFast_SrcRectConstraint, viewMatrix, paint); + GrTextureAdjuster adjuster(this->context(), std::move(proxy), + image->alphaType(), image->bounds(), + pinnedUniqueID, as_IB(image)->onImageInfo().colorSpace()); + this->drawTextureProducer(&adjuster, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint, + viewMatrix, this->clip(), paint); return; - } - SkBitmap bm; - if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstraint, - paint.getFilterQuality(), viewMatrix, SkMatrix::I())) { - // only support tiling as bitmap at the moment, so force raster-version - if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) { - return; + } else { + SkBitmap bm; + if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstraint, + paint.getFilterQuality(), this->ctm(), SkMatrix::I())) { + // only support tiling as bitmap at the moment, so force raster-version + if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) { + return; + } + this->drawBitmap(bm, x, y, paint); + } else if (image->isLazyGenerated()) { + GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint); + this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint, + viewMatrix, this->clip(), paint); + } else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) { + GrBitmapTextureMaker maker(fContext.get(), bm); + this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint, + viewMatrix, this->clip(), paint); } - this->drawBitmap(bm, x, y, paint); - return; - } - if (image->isLazyGenerated()) { - GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint); - this->drawTextureMaker(&maker, image->width(), image->height(), nullptr, nullptr, - SkCanvas::kFast_SrcRectConstraint, viewMatrix, paint); - return; - } - if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) { - GrBitmapTextureMaker maker(fContext.get(), bm); - this->drawTextureMaker(&maker, image->width(), image->height(), nullptr, nullptr, - SkCanvas::kFast_SrcRectConstraint, viewMatrix, paint); } } -void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, - const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) { +void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src, + const SkRect& dst, const SkPaint& paint, + SkCanvas::SrcRectConstraint constraint) { ASSERT_SINGLE_OWNER uint32_t pinnedUniqueID; - if (!src || src->contains(image->bounds())) { - constraint = SkCanvas::kFast_SrcRectConstraint; - } if (sk_sp proxy = as_IB(image)->refPinnedTextureProxy(&pinnedUniqueID)) { - this->drawPinnedTextureProxy(std::move(proxy), pinnedUniqueID, as_IB(image)->colorSpace(), - image->alphaType(), src, &dst, constraint, this->ctm(), paint); + GrTextureAdjuster adjuster(this->context(), std::move(proxy), + image->alphaType(), image->bounds(), pinnedUniqueID, + as_IB(image)->onImageInfo().colorSpace()); + this->drawTextureProducer(&adjuster, src, &dst, constraint, this->ctm(), this->clip(), + paint); return; } SkBitmap bm; @@ -1343,18 +1348,12 @@ void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src, const S return; } this->drawBitmapRect(bm, src, dst, paint, constraint); - return; - } - if (image->isLazyGenerated()) { + } else if (image->isLazyGenerated()) { GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint); - this->drawTextureMaker(&maker, image->width(), image->height(), src, &dst, constraint, - this->ctm(), paint); - return; - } - if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) { + this->drawTextureProducer(&maker, src, &dst, constraint, this->ctm(), this->clip(), paint); + } else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) { GrBitmapTextureMaker maker(fContext.get(), bm); - this->drawTextureMaker(&maker, image->width(), image->height(), src, &dst, constraint, - this->ctm(), paint); + this->drawTextureProducer(&maker, src, &dst, constraint, this->ctm(), this->clip(), paint); } } @@ -1374,7 +1373,7 @@ void SkGpuDevice::drawProducerNine(GrTextureProducer* producer, SkRect srcR, dstR; while (iter.next(&srcR, &dstR)) { this->drawTextureProducer(producer, &srcR, &dstR, SkCanvas::kStrict_SrcRectConstraint, - this->ctm(), paint); + this->ctm(), this->clip(), paint); } return; } diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 0b7e286aae..f1bd937269 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -21,7 +21,6 @@ #include "GrTypes.h" class GrAccelData; -class GrTextureMaker; class GrTextureProducer; struct GrCachedLayer; @@ -206,30 +205,12 @@ private: bool bicubic, bool needsTextureDomain); - void drawPinnedTextureProxy(sk_sp, - uint32_t pinnedUniqueID, - SkColorSpace*, - SkAlphaType alphaType, - const SkRect* srcRect, - const SkRect* dstRect, - SkCanvas::SrcRectConstraint, - const SkMatrix& viewMatrix, - const SkPaint&); - - void drawTextureMaker(GrTextureMaker* maker, - int imageW, - int imageH, - const SkRect* srcRect, - const SkRect* dstRect, - SkCanvas::SrcRectConstraint, - const SkMatrix& viewMatrix, - const SkPaint&); - void drawTextureProducer(GrTextureProducer*, const SkRect* srcRect, const SkRect* dstRect, SkCanvas::SrcRectConstraint, const SkMatrix& viewMatrix, + const GrClip&, const SkPaint&); void drawTextureProducerImpl(GrTextureProducer*, @@ -238,6 +219,7 @@ private: SkCanvas::SrcRectConstraint, const SkMatrix& viewMatrix, const SkMatrix& srcToDstMatrix, + const GrClip&, const SkPaint&); bool drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& outer, diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp index c861cc919e..6fa171113b 100644 --- a/src/gpu/SkGpuDevice_drawTexture.cpp +++ b/src/gpu/SkGpuDevice_drawTexture.cpp @@ -6,12 +6,12 @@ */ #include "SkGpuDevice.h" + #include "GrBlurUtils.h" #include "GrCaps.h" #include "GrRenderTargetContext.h" #include "GrStyle.h" #include "GrTextureAdjuster.h" -#include "GrTextureMaker.h" #include "SkDraw.h" #include "SkGr.h" #include "SkMaskFilter.h" @@ -85,98 +85,14 @@ static bool can_ignore_bilerp_constraint(const GrTextureProducer& producer, return false; } -/** - * Checks whether the paint, matrix, and constraint are compatible with using - * GrRenderTargetContext::drawTextureAffine. It is more effecient than the GrTextureProducer - * general case. - */ -static bool can_use_draw_texture_affine(const SkPaint& paint, const SkMatrix& ctm, - SkCanvas::SrcRectConstraint constraint) { - return (!paint.getColorFilter() && !paint.getShader() && !paint.getMaskFilter() && - !paint.getImageFilter() && !paint.isAntiAlias() && - paint.getFilterQuality() < kMedium_SkFilterQuality && - paint.getBlendMode() == SkBlendMode::kSrcOver && !ctm.hasPerspective() && - SkCanvas::kFast_SrcRectConstraint == constraint); -} - -static void draw_texture_affine(const SkPaint& paint, const SkMatrix& ctm, const SkRect* src, - const SkRect* dst, sk_sp proxy, - SkColorSpace* colorSpace, const GrClip& clip, - GrRenderTargetContext* rtc) { - SkASSERT(!(SkToBool(src) && !SkToBool(dst))); - SkRect srcRect = src ? *src : SkRect::MakeWH(proxy->width(), proxy->height()); - SkRect dstRect = dst ? *dst : srcRect; - if (src && !SkRect::MakeIWH(proxy->width(), proxy->height()).contains(srcRect)) { - // Shrink the src rect to be within bounds and proportionately shrink the dst rect. - SkMatrix srcToDst; - srcToDst.setRectToRect(srcRect, dstRect, SkMatrix::kFill_ScaleToFit); - SkAssertResult(srcRect.intersect(SkRect::MakeIWH(proxy->width(), proxy->height()))); - srcToDst.mapRect(&dstRect, srcRect); - } - auto csxf = GrColorSpaceXform::Make(colorSpace, rtc->getColorSpace()); - GrSamplerParams::FilterMode filter; - switch (paint.getFilterQuality()) { - case kNone_SkFilterQuality: - filter = GrSamplerParams::kNone_FilterMode; - break; - case kLow_SkFilterQuality: - filter = GrSamplerParams::kBilerp_FilterMode; - break; - case kMedium_SkFilterQuality: - case kHigh_SkFilterQuality: - SK_ABORT("Quality level not allowed."); - } - GrColor color = GrPixelConfigIsAlphaOnly(proxy->config()) - ? SkColorToPremulGrColor(paint.getColor()) - : SkColorAlphaToGrColor(paint.getColor()); - rtc->drawTextureAffine(clip, std::move(proxy), filter, color, srcRect, dstRect, ctm, - std::move(csxf)); -} - ////////////////////////////////////////////////////////////////////////////// -void SkGpuDevice::drawPinnedTextureProxy(sk_sp proxy, uint32_t pinnedUniqueID, - SkColorSpace* colorSpace, SkAlphaType alphaType, - const SkRect* srcRect, const SkRect* dstRect, - SkCanvas::SrcRectConstraint constraint, - const SkMatrix& viewMatrix, const SkPaint& paint) { - if (can_use_draw_texture_affine(paint, this->ctm(), constraint)) { - draw_texture_affine(paint, viewMatrix, srcRect, dstRect, std::move(proxy), colorSpace, - this->clip(), fRenderTargetContext.get()); - return; - } - auto contentRect = SkIRect::MakeWH(proxy->width(), proxy->height()); - GrTextureAdjuster adjuster(this->context(), std::move(proxy), alphaType, contentRect, - pinnedUniqueID, colorSpace); - this->drawTextureProducer(&adjuster, srcRect, dstRect, constraint, viewMatrix, paint); -} - -void SkGpuDevice::drawTextureMaker(GrTextureMaker* maker, int imageW, int imageH, - const SkRect* srcRect, const SkRect* dstRect, - SkCanvas::SrcRectConstraint constraint, - const SkMatrix& viewMatrix, const SkPaint& paint) { - if (can_use_draw_texture_affine(paint, viewMatrix, constraint)) { - sk_sp cs; - // We've done enough checks above to allow us to pass ClampNoFilter() and not check for - // scaling adjustments. - auto proxy = maker->refTextureProxyForParams(GrSamplerParams::ClampNoFilter(), - fRenderTargetContext->getColorSpace(), &cs, - nullptr); - if (!proxy) { - return; - } - draw_texture_affine(paint, viewMatrix, srcRect, dstRect, std::move(proxy), cs.get(), - this->clip(), fRenderTargetContext.get()); - return; - } - this->drawTextureProducer(maker, srcRect, dstRect, constraint, viewMatrix, paint); -} - void SkGpuDevice::drawTextureProducer(GrTextureProducer* producer, const SkRect* srcRect, const SkRect* dstRect, SkCanvas::SrcRectConstraint constraint, const SkMatrix& viewMatrix, + const GrClip& clip, const SkPaint& paint) { // This is the funnel for all non-tiled bitmap/image draw calls. Log a histogram entry. SK_HISTOGRAM_BOOLEAN("DrawTiled", false); @@ -225,7 +141,7 @@ void SkGpuDevice::drawTextureProducer(GrTextureProducer* producer, LogDrawScaleFactor(SkMatrix::Concat(viewMatrix, srcToDstMatrix), paint.getFilterQuality()); this->drawTextureProducerImpl(producer, clippedSrcRect, clippedDstRect, constraint, viewMatrix, - srcToDstMatrix, paint); + srcToDstMatrix, clip, paint); } void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer, @@ -234,6 +150,7 @@ void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer, 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 GrDrawOp // combining by not baking anything about the srcRect, dstRect, or viewMatrix, into the texture @@ -298,14 +215,13 @@ void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer, } GrAA aa = GrBoolToAA(paint.isAntiAlias()); if (canUseTextureCoordsAsLocalCoords) { - fRenderTargetContext->fillRectToRect(this->clip(), std::move(grPaint), aa, viewMatrix, + fRenderTargetContext->fillRectToRect(clip, std::move(grPaint), aa, viewMatrix, clippedDstRect, clippedSrcRect); return; } if (!mf) { - fRenderTargetContext->drawRect(this->clip(), std::move(grPaint), aa, viewMatrix, - clippedDstRect); + fRenderTargetContext->drawRect(clip, std::move(grPaint), aa, viewMatrix, clippedDstRect); return; } @@ -318,7 +234,7 @@ void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer, if (mf->directFilterRRectMaskGPU(fContext.get(), fRenderTargetContext.get(), std::move(grPaint), - this->clip(), + clip, viewMatrix, rec, SkRRect::MakeRect(clippedDstRect), diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp deleted file mode 100644 index 695565ebd4..0000000000 --- a/src/gpu/ops/GrTextureOp.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrTextureOp.h" -#include "GrAppliedClip.h" -#include "GrDrawOpTest.h" -#include "GrGeometryProcessor.h" -#include "GrMeshDrawOp.h" -#include "GrOpFlushState.h" -#include "GrQuad.h" -#include "GrResourceProvider.h" -#include "GrTexture.h" -#include "GrTextureProxy.h" -#include "SkGr.h" -#include "glsl/GrGLSLColorSpaceXformHelper.h" -#include "glsl/GrGLSLGeometryProcessor.h" -#include "glsl/GrGLSLVarying.h" - -namespace { - -/** - * Geometry Processor that draws a texture modulated by a per-vertex color. Used by TextureOp - * below. - */ -class TextureGeometryProcessor : public GrGeometryProcessor { -public: - struct Vertex { - SkPoint fPosition; - SkPoint fTextureCoords; - GrColor fColor; - }; - static sk_sp Make(sk_sp proxy, - sk_sp csxf, - GrSamplerParams::FilterMode filter) { - return sk_sp( - new TextureGeometryProcessor(std::move(proxy), std::move(csxf), filter)); - } - - const char* name() const override { return "TextureGeometryProcessor"; } - - void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { - b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get())); - } - - GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override { - class GLSLProcessor : public GrGLSLGeometryProcessor { - public: - void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, - FPCoordTransformIter&& transformIter) override { - const auto& textureGP = proc.cast(); - this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); - if (fColorSpaceXformHelper.isValid()) { - fColorSpaceXformHelper.setData(pdman, textureGP.fColorSpaceXform.get()); - } - } - - private: - void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { - const auto& textureGP = args.fGP.cast(); - fColorSpaceXformHelper.emitCode( - args.fUniformHandler, textureGP.fColorSpaceXform.get()); - args.fVaryingHandler->setNoPerspective(); - args.fVaryingHandler->emitAttributes(textureGP); - this->writeOutputPosition(args.fVertBuilder, gpArgs, textureGP.fPositions.fName); - this->emitTransforms(args.fVertBuilder, - args.fVaryingHandler, - args.fUniformHandler, - gpArgs->fPositionVar, - textureGP.fTextureCoords.fName, - args.fFPCoordTransformHandler); - args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fColors, - args.fOutputColor); - args.fFragBuilder->codeAppend("highp float2 texCoord;"); - args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureCoords, - "texCoord"); - args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor); - args.fFragBuilder->appendTextureLookupAndModulate(args.fOutputColor, - args.fTexSamplers[0], - "texCoord", - kVec2f_GrSLType, - &fColorSpaceXformHelper); - args.fFragBuilder->codeAppend(";"); - args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage); - } - GrGLSLColorSpaceXformHelper fColorSpaceXformHelper; - }; - return new GLSLProcessor; - } - -private: - TextureGeometryProcessor(sk_sp proxy, sk_sp csxf, - GrSamplerParams::FilterMode filter) - : fSampler(std::move(proxy), filter), fColorSpaceXform(std::move(csxf)) { - this->initClassID(); - fPositions = - this->addVertexAttrib("position", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); - fTextureCoords = this->addVertexAttrib("textureCoords", kVec2f_GrVertexAttribType, - kHigh_GrSLPrecision); - fColors = this->addVertexAttrib("color", kVec4ub_GrVertexAttribType); - this->addTextureSampler(&fSampler); - } - - Attribute fPositions; - Attribute fTextureCoords; - Attribute fColors; - TextureSampler fSampler; - sk_sp fColorSpaceXform; -}; - -/** - * Op that implements GrTextureOp::Make. It draws textured quads. Each quad can modulate against a - * the texture by color. The blend with the destination is always src-over. The edges are non-AA. - */ -class TextureOp final : public GrMeshDrawOp { -public: - static std::unique_ptr Make(sk_sp proxy, - GrSamplerParams::FilterMode filter, GrColor color, - const SkRect srcRect, const SkRect dstRect, - const SkMatrix& viewMatrix, sk_sp csxf, - bool allowSRBInputs) { - return std::unique_ptr(new TextureOp(std::move(proxy), filter, color, srcRect, - dstRect, viewMatrix, std::move(csxf), - allowSRBInputs)); - } - - ~TextureOp() override { fFinalized ? fProxy->completedRead() : fProxy->unref(); } - - const char* name() const override { return "TextureOp"; } - - SkString dumpInfo() const override { - SkString str; - str.appendf("Filter: %d AllowSRGBInputs: %d\n", fFilter, fAllowSRGBInputs); - str.appendf("# draws: %d\n", fDraws.count()); - for (int i = 0; i < fDraws.count(); ++i) { - const Draw& draw = fDraws[i]; - str.appendf( - "%d: Color: 0x%08x, TexRect [L: %.2f, T: %.2f, R: %.2f, B: %.2f] Quad [(%.2f, " - "%.2f), (%.2f, %.2f), (%.2f, %.2f), (%.2f, %.2f)]\n", - i, draw.fColor, draw.fSrcRect.fLeft, draw.fSrcRect.fTop, draw.fSrcRect.fRight, - draw.fSrcRect.fBottom, draw.fQuad.points()[0].fX, draw.fQuad.points()[0].fY, - draw.fQuad.points()[1].fX, draw.fQuad.points()[1].fY, draw.fQuad.points()[2].fX, - draw.fQuad.points()[2].fY, draw.fQuad.points()[3].fX, - draw.fQuad.points()[3].fY); - } - str += INHERITED::dumpInfo(); - return str; - } - - RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override { - SkASSERT(!fFinalized); - fFinalized = true; - fProxy->addPendingRead(); - fProxy->unref(); - return RequiresDstTexture::kNo; - } - - FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } - - DEFINE_OP_CLASS_ID - -private: - TextureOp(sk_sp proxy, GrSamplerParams::FilterMode filter, GrColor color, - const SkRect& srcRect, const SkRect& dstRect, const SkMatrix& viewMatrix, - sk_sp csxf, bool allowSRGBInputs) - : INHERITED(ClassID()) - , fProxy(proxy.release()) - , fFilter(filter) - , fColorSpaceXform(std::move(csxf)) - , fFinalized(false) - , fAllowSRGBInputs(allowSRGBInputs) { - Draw& draw = fDraws.push_back(); - draw.fSrcRect = srcRect; - draw.fColor = color; - draw.fQuad.setFromMappedRect(dstRect, viewMatrix); - SkRect bounds; - bounds.setBounds(draw.fQuad.points(), 4); - this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); - } - - void onPrepareDraws(Target* target) override { - if (!fProxy->instantiate(target->resourceProvider())) { - return; - } - sk_sp gp = TextureGeometryProcessor::Make( - sk_ref_sp(fProxy), std::move(fColorSpaceXform), fFilter); - GrPipeline::InitArgs args; - args.fProxy = target->proxy(); - args.fCaps = &target->caps(); - args.fResourceProvider = target->resourceProvider(); - args.fFlags = fAllowSRGBInputs ? GrPipeline::kAllowSRGBInputs_Flag : 0; - const GrPipeline* pipeline = target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), - target->detachAppliedClip()); - - using Vertex = TextureGeometryProcessor::Vertex; - SkASSERT(gp->getVertexStride() == sizeof(Vertex)); - - int vstart; - const GrBuffer* vbuffer; - auto vertices = (Vertex*)target->makeVertexSpace(sizeof(Vertex), 4 * fDraws.count(), - &vbuffer, &vstart); - if (!vertices) { - SkDebugf("Could not allocate vertices\n"); - return; - } - sk_sp ibuffer; - if (fDraws.count() > 1) { - ibuffer.reset(target->resourceProvider()->refQuadIndexBuffer()); - if (!ibuffer) { - SkDebugf("Could not allocate quad indices\n"); - return; - } - } - GrTexture* texture = fProxy->priv().peekTexture(); - float iw = 1.f / texture->width(); - float ih = 1.f / texture->height(); - if (fDraws.count() > 1) { - for (int i = 0; i < fDraws.count(); ++i) { - float tl = iw * fDraws[i].fSrcRect.fLeft; - float tr = iw * fDraws[i].fSrcRect.fRight; - float tt = ih * fDraws[i].fSrcRect.fTop; - float tb = ih * fDraws[i].fSrcRect.fBottom; - if (fProxy->origin() == kBottomLeft_GrSurfaceOrigin) { - tt = 1.f - tt; - tb = 1.f - tb; - } - vertices[0 + 4 * i].fPosition = fDraws[i].fQuad.points()[0]; - vertices[0 + 4 * i].fTextureCoords = {tl, tt}; - vertices[0 + 4 * i].fColor = fDraws[i].fColor; - vertices[1 + 4 * i].fPosition = fDraws[i].fQuad.points()[1]; - vertices[1 + 4 * i].fTextureCoords = {tl, tb}; - vertices[1 + 4 * i].fColor = fDraws[i].fColor; - vertices[2 + 4 * i].fPosition = fDraws[i].fQuad.points()[2]; - vertices[2 + 4 * i].fTextureCoords = {tr, tb}; - vertices[2 + 4 * i].fColor = fDraws[i].fColor; - vertices[3 + 4 * i].fPosition = fDraws[i].fQuad.points()[3]; - vertices[3 + 4 * i].fTextureCoords = {tr, tt}; - vertices[3 + 4 * i].fColor = fDraws[i].fColor; - } - GrMesh mesh(GrPrimitiveType::kTriangles); - mesh.setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(), - GrResourceProvider::QuadCountOfQuadBuffer()); - mesh.setVertexData(vbuffer, vstart); - target->draw(gp.get(), pipeline, mesh); - } else { - float tl = iw * fDraws[0].fSrcRect.fLeft; - float tr = iw * fDraws[0].fSrcRect.fRight; - float tt = ih * fDraws[0].fSrcRect.fTop; - float tb = ih * fDraws[0].fSrcRect.fBottom; - if (fProxy->origin() == kBottomLeft_GrSurfaceOrigin) { - tt = 1.f - tt; - tb = 1.f - tb; - } - vertices[0].fPosition = fDraws[0].fQuad.points()[0]; - vertices[0].fTextureCoords = {tl, tt}; - vertices[0].fColor = fDraws[0].fColor; - vertices[1].fPosition = fDraws[0].fQuad.points()[3]; - vertices[1].fTextureCoords = {tr, tt}; - vertices[1].fColor = fDraws[0].fColor; - vertices[2].fPosition = fDraws[0].fQuad.points()[1]; - vertices[2].fTextureCoords = {tl, tb}; - vertices[2].fColor = fDraws[0].fColor; - vertices[3].fPosition = fDraws[0].fQuad.points()[2]; - vertices[3].fTextureCoords = {tr, tb}; - vertices[3].fColor = fDraws[0].fColor; - GrMesh mesh(GrPrimitiveType::kTriangleStrip); - mesh.setNonIndexedNonInstanced(4); - mesh.setVertexData(vbuffer, vstart); - target->draw(gp.get(), pipeline, mesh); - } - } - - bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { - const auto* that = t->cast(); - if (fProxy->uniqueID() != that->fProxy->uniqueID() || fFilter != that->fFilter || - !GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get())) { - return false; - } - fDraws.push_back_n(that->fDraws.count(), that->fDraws.begin()); - this->joinBounds(*that); - return true; - } - - struct Draw { - SkRect fSrcRect; - GrQuad fQuad; - GrColor fColor; - }; - SkSTArray<1, Draw, true> fDraws; - GrTextureProxy* fProxy; - GrSamplerParams::FilterMode fFilter; - sk_sp fColorSpaceXform; - // Used to track whether fProxy is ref'ed or has a pending IO after finalize() is called. - bool fFinalized : 1; - bool fAllowSRGBInputs : 1; - typedef GrMeshDrawOp INHERITED; -}; - -} // anonymous namespace - -namespace GrTextureOp { - -std::unique_ptr Make(sk_sp proxy, GrSamplerParams::FilterMode filter, - GrColor color, const SkRect& srcRect, const SkRect& dstRect, - const SkMatrix& viewMatrix, sk_sp csxf, - bool allowSRGBInputs) { - SkASSERT(!viewMatrix.hasPerspective()); - return TextureOp::Make(std::move(proxy), filter, color, srcRect, dstRect, viewMatrix, - std::move(csxf), allowSRGBInputs); -} - -} // namespace GrTextureOp - -#if GR_TEST_UTILS -#include "GrContext.h" - -GR_DRAW_OP_TEST_DEFINE(TextureOp) { - GrSurfaceDesc desc; - desc.fConfig = kRGBA_8888_GrPixelConfig; - desc.fHeight = random->nextULessThan(90) + 10; - desc.fWidth = random->nextULessThan(90) + 10; - desc.fOrigin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin; - SkBackingFit fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact; - auto proxy = - GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc, fit, SkBudgeted::kNo); - SkRect rect = GrTest::TestRect(random); - SkRect srcRect; - srcRect.fLeft = random->nextRangeScalar(0.f, proxy->width() / 2.f); - srcRect.fRight = random->nextRangeScalar(0.f, proxy->width()) + proxy->width() / 2.f; - srcRect.fTop = random->nextRangeScalar(0.f, proxy->height() / 2.f); - srcRect.fBottom = random->nextRangeScalar(0.f, proxy->height()) + proxy->height() / 2.f; - SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random); - GrColor color = SkColorToPremulGrColor(random->nextU()); - GrSamplerParams::FilterMode filter = (GrSamplerParams::FilterMode)random->nextULessThan( - GrSamplerParams::kMipMap_FilterMode + 1); - auto csxf = GrTest::TestColorXform(random); - bool allowSRGBInputs = random->nextBool(); - return GrTextureOp::Make(std::move(proxy), filter, color, srcRect, rect, viewMatrix, - std::move(csxf), allowSRGBInputs); -} - -#endif diff --git a/src/gpu/ops/GrTextureOp.h b/src/gpu/ops/GrTextureOp.h deleted file mode 100644 index cf6a227769..0000000000 --- a/src/gpu/ops/GrTextureOp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrColor.h" -#include "GrColorSpaceXform.h" -#include "GrSamplerParams.h" - -class GrDrawOp; -class GrTextureProxy; -struct SkRect; -class SkMatrix; - -namespace GrTextureOp { -/** - * Creates an op that draws a sub-rectangle of a texture. The passed color is modulated by the - * texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect' specifies - * the rectangle to draw in local coords which will be transformed by 'viewMatrix' to be in device - * space. 'viewMatrix' must be affine. - */ -std::unique_ptr Make(sk_sp, GrSamplerParams::FilterMode, GrColor, - const SkRect& srcRect, const SkRect& dstRect, - const SkMatrix& viewMatrix, sk_sp, - bool allowSRGBInputs); -} -- cgit v1.2.3