Remove support for copyAsDraw in gpu copySurface.
The major changes on a higher lever are:
1) The majority of all copies now go through GrSurfaceProxy::Copy which
takes in a proxy and returns a new one with the data copied to it. This
is the most common use case within Ganesh.
2) The backend copy calls no longer do draws, require origins to be the
same, and won't do any swizzling or adjustment of subrects. They are
all implemented to be dumb copy this data to this other spot.
3) The GrSurfaceContext copy call has now been moved to priv and renamed
copyNoDraw, and a new priv copyAsDraw was added to GrRenderTargetContext.
4) WritePixels and ReplaceRenderTarget both need to specifiy the destination
of copies. They are the only users (besides the GrSurfaceProxy::Copy) which
call the priv methods on GrSurfaceContext.
Change-Id: Iaf1eb3a73ccaf39a75af77e281dae594f809186f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/217459
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 4df0bd4..6320809 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -208,28 +208,10 @@
// because Vulkan will want to do the copy as a draw. All other copies would require a
// layout change in Vulkan and we do not change the layout of borrowed images.
GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
-
- GrBackendFormat format = proxy->backendFormat().makeTexture2D();
- if (!format.isValid()) {
- return nullptr;
- }
-
- sk_sp<GrRenderTargetContext> rtContext(
- context->priv().makeDeferredRenderTargetContext(
- format, SkBackingFit::kExact, info.width(), info.height(),
- proxy->config(), nullptr, 1, mipMapped, proxy->origin(), nullptr,
- SkBudgeted::kYes));
-
- if (!rtContext) {
- return nullptr;
- }
-
SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
- if (!rtContext->copy(proxy.get(), subset, SkIPoint::Make(0, 0))) {
- return nullptr;
- }
- return rtContext->asTextureProxyRef();
+ return GrSurfaceProxy::Copy(context, proxy.get(), mipMapped, subset, SkBackingFit::kExact,
+ SkBudgeted::kYes);
}
}
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 3c9884e..42d6e76 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -310,8 +310,7 @@
* copy rect must equal src's bounds.
*/
virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
- GrSurfaceOrigin* origin, bool* rectsMustMatch,
- bool* disallowSubrect) const = 0;
+ bool* rectsMustMatch, bool* disallowSubrect) const = 0;
bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const;
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index 7945192..a311de0 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -16,6 +16,7 @@
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrSurfacePriv.h"
+#include "src/gpu/GrSurfaceContextPriv.h"
#include "src/gpu/GrTextureContext.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/generated/GrConfigConversionEffect.h"
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index ce151b1..7bbedfc 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -222,10 +222,8 @@
return buffer;
}
-bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) {
+bool GrGpu::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) {
GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "copySurface", fContext);
SkASSERT(dst && src);
@@ -235,8 +233,7 @@
this->handleDirtyContext();
- return this->onCopySurface(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint,
- canDiscardOutsideDstRect);
+ return this->onCopySurface(dst, src, srcRect, dstPoint, canDiscardOutsideDstRect);
}
bool GrGpu::readPixels(GrSurface* surface, int left, int top, int width, int height,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 467e1db..62d435e 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -253,13 +253,11 @@
// Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
// take place at the GrOpList level and this function implement faster copy paths. The rect
// and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the
- // src/dst bounds and non-empty. If canDiscardOutsideDstRect is set to true then we don't need
- // to preserve any data on the dst surface outside of the copy.
- bool copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect = false);
+ // src/dst bounds and non-empty. They must also be in their exact device space coords, including
+ // already being transformed for origin if need be. If canDiscardOutsideDstRect is set to true
+ // then we don't need to preserve any data on the dst surface outside of the copy.
+ bool copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect = false);
// Queries the per-pixel HW sample locations for the given render target, and then finds or
// assigns a key that uniquely identifies the sample pattern. The actual sample locations can be
@@ -537,10 +535,8 @@
virtual bool onRegenerateMipMapLevels(GrTexture*) = 0;
// overridden by backend specific derived class to perform the copy surface
- virtual bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) = 0;
+ virtual bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) = 0;
virtual void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
const GrFlushInfo&, const GrPrepareForExternalIORequests&) = 0;
diff --git a/src/gpu/GrGpuCommandBuffer.h b/src/gpu/GrGpuCommandBuffer.h
index abb3c4d..e96c610 100644
--- a/src/gpu/GrGpuCommandBuffer.h
+++ b/src/gpu/GrGpuCommandBuffer.h
@@ -30,9 +30,9 @@
virtual ~GrGpuCommandBuffer() {}
// Copy src into current surface owned by either a GrGpuTextureCommandBuffer or
- // GrGpuRenderTargetCommandBuffer.
- virtual void copy(GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) = 0;
+ // GrGpuRenderTargetCommandBuffer. The srcRect and dstPoint must be in dst coords and have
+ // already been adjusted for any origin flips.
+ virtual void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) = 0;
// Initiates a transfer from the surface owned by the command buffer to the GrGpuBuffer.
virtual void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) = 0;
@@ -47,19 +47,14 @@
void set(GrTexture* texture, GrSurfaceOrigin origin) {
SkASSERT(!fTexture);
- fOrigin = origin;
fTexture = texture;
}
protected:
- GrGpuTextureCommandBuffer() : fOrigin(kTopLeft_GrSurfaceOrigin), fTexture(nullptr) {}
+ GrGpuTextureCommandBuffer() : fTexture(nullptr) {}
- GrGpuTextureCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin)
- : fOrigin(origin)
- , fTexture(texture) {
- }
+ GrGpuTextureCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin) : fTexture(texture) {}
- GrSurfaceOrigin fOrigin;
GrTexture* fTexture;
private:
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 6b77d30..d44da83 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1785,27 +1785,17 @@
int srcH = srcRect.height();
int srcX = srcRect.fLeft;
int srcY = srcRect.fTop;
- sk_sp<GrSurfaceContext> srcContext = sk_ref_sp(this);
+ sk_sp<GrTextureProxy> texProxy = sk_ref_sp(fRenderTargetProxy->asTextureProxy());
SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
- if (!this->asTextureProxy()) {
- GrSurfaceDesc desc;
- desc.fWidth = srcW;
- desc.fHeight = srcH;
- desc.fConfig = fRenderTargetProxy->config();
- auto sContext = direct->priv().makeDeferredSurfaceContext(
- fRenderTargetProxy->backendFormat().makeTexture2D(), desc, this->origin(),
- GrMipMapped::kNo, SkBackingFit::kApprox, SkBudgeted::kNo,
- this->colorSpaceInfo().refColorSpace());
- if (!sContext) {
- return nullptr;
- }
- if (!sContext->copy(fRenderTargetProxy.get(), srcRect, {0, 0})) {
+ if (!texProxy) {
+ texProxy = GrSurfaceProxy::Copy(fContext, fRenderTargetProxy.get(), GrMipMapped::kNo,
+ srcRect, SkBackingFit::kApprox, SkBudgeted::kNo);
+ if (!texProxy) {
return nullptr;
}
srcX = 0;
srcY = 0;
constraint = SkCanvas::kFast_SrcRectConstraint;
- srcContext = std::move(sContext);
}
float sx = (float)info.width() / srcW;
@@ -1824,33 +1814,35 @@
stepsY = sy != 1.f;
}
SkASSERT(stepsX || stepsY);
+ auto currentColorSpace = this->colorSpaceInfo().refColorSpace();
// Assume we should ignore the rescale linear request if the surface has no color space since
// it's unclear how we'd linearize from an unknown color space.
if (rescaleGamma == SkSurface::RescaleGamma::kLinear &&
- srcContext->colorSpaceInfo().colorSpace() &&
- !srcContext->colorSpaceInfo().colorSpace()->gammaIsLinear()) {
- auto cs = srcContext->colorSpaceInfo().colorSpace()->makeLinearGamma();
+ currentColorSpace.get() && !currentColorSpace->gammaIsLinear()) {
+ auto cs = currentColorSpace->makeLinearGamma();
auto backendFormat = this->caps()->getBackendFormatFromGrColorType(GrColorType::kRGBA_F16,
GrSRGBEncoded::kNo);
- auto xform = GrColorSpaceXform::Make(srcContext->colorSpaceInfo().colorSpace(),
- kPremul_SkAlphaType, cs.get(), kPremul_SkAlphaType);
+ auto xform = GrColorSpaceXform::Make(currentColorSpace.get(), kPremul_SkAlphaType, cs.get(),
+ kPremul_SkAlphaType);
// We'll fall back to kRGBA_8888 if half float not supported.
auto linearRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
- backendFormat, SkBackingFit::kExact, srcW, srcH, kRGBA_half_GrPixelConfig,
- std::move(cs), 1, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
+ backendFormat, SkBackingFit::kExact, srcW, srcH, kRGBA_half_GrPixelConfig, cs, 1,
+ GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
if (!linearRTC) {
return nullptr;
}
- linearRTC->drawTexture(GrNoClip(), srcContext->asTextureProxyRef(),
+ linearRTC->drawTexture(GrNoClip(), texProxy,
GrSamplerState::Filter::kNearest, SkBlendMode::kSrc,
SK_PMColor4fWHITE, SkRect::Make(srcRect), SkRect::MakeWH(srcW, srcH),
GrAA::kNo, GrQuadAAFlags::kNone, constraint, SkMatrix::I(),
std::move(xform));
- srcContext = std::move(linearRTC);
+ texProxy = linearRTC->asTextureProxyRef();
+ currentColorSpace = std::move(cs);
srcX = 0;
srcY = 0;
constraint = SkCanvas::kFast_SrcRectConstraint;
}
+ sk_sp<GrRenderTargetContext> currRTC;
while (stepsX || stepsY) {
int nextW = info.width();
int nextH = info.height();
@@ -1872,23 +1864,22 @@
}
--stepsY;
}
- GrBackendFormat backendFormat =
- srcContext->asSurfaceProxy()->backendFormat().makeTexture2D();
- GrPixelConfig config = srcContext->asSurfaceProxy()->config();
- auto cs = srcContext->colorSpaceInfo().refColorSpace();
+ GrBackendFormat backendFormat = texProxy->backendFormat().makeTexture2D();
+ GrPixelConfig config = texProxy->config();
+ auto cs = currentColorSpace;
sk_sp<GrColorSpaceXform> xform;
if (!stepsX && !stepsY) {
// Might as well fold conversion to final info in the last step.
backendFormat = this->caps()->getBackendFormatFromColorType(info.colorType());
config = this->caps()->getConfigFromBackendFormat(backendFormat, info.colorType());
cs = info.refColorSpace();
- xform = GrColorSpaceXform::Make(srcContext->colorSpaceInfo().colorSpace(),
+ xform = GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(),
kPremul_SkAlphaType, cs.get(), info.alphaType());
}
- auto nextRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
+ currRTC = fContext->priv().makeDeferredRenderTargetContextWithFallback(
backendFormat, SkBackingFit::kExact, nextW, nextH, config, std::move(cs), 1,
GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
- if (!nextRTC) {
+ if (!currRTC) {
return nullptr;
}
auto dstRect = SkRect::MakeWH(nextW, nextH);
@@ -1902,14 +1893,12 @@
} else if (nextH == srcH) {
dir = GrBicubicEffect::Direction::kX;
}
- if (srcW != srcContext->width() || srcH != srcContext->height()) {
+ if (srcW != texProxy->width() || srcH != texProxy->height()) {
auto domain = GrTextureDomain::MakeTexelDomain(
SkIRect::MakeXYWH(srcX, srcY, srcW, srcH), GrTextureDomain::kClamp_Mode);
- fp = GrBicubicEffect::Make(srcContext->asTextureProxyRef(), matrix, domain, dir,
- kPremul_SkAlphaType);
+ fp = GrBicubicEffect::Make(texProxy, matrix, domain, dir, kPremul_SkAlphaType);
} else {
- fp = GrBicubicEffect::Make(srcContext->asTextureProxyRef(), matrix, dir,
- kPremul_SkAlphaType);
+ fp = GrBicubicEffect::Make(texProxy, matrix, dir, kPremul_SkAlphaType);
}
if (xform) {
fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(xform));
@@ -1917,26 +1906,24 @@
GrPaint paint;
paint.addColorFragmentProcessor(std::move(fp));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- nextRTC->drawFilledRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
+ currRTC->drawFilledRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
dstRect);
} else {
auto filter = rescaleQuality == kNone_SkFilterQuality ? GrSamplerState::Filter::kNearest
: GrSamplerState::Filter::kBilerp;
auto srcSubset = SkRect::MakeXYWH(srcX, srcY, srcW, srcH);
- nextRTC->drawTexture(GrNoClip(), srcContext->asTextureProxyRef(), filter,
- SkBlendMode::kSrc, SK_PMColor4fWHITE, srcSubset, dstRect,
- GrAA::kNo, GrQuadAAFlags::kNone, constraint, SkMatrix::I(),
- std::move(xform));
+ currRTC->drawTexture(GrNoClip(), texProxy, filter, SkBlendMode::kSrc, SK_PMColor4fWHITE,
+ srcSubset, dstRect, GrAA::kNo, GrQuadAAFlags::kNone, constraint,
+ SkMatrix::I(), std::move(xform));
}
- srcContext = std::move(nextRTC);
+ texProxy = currRTC->asTextureProxyRef();
srcX = srcY = 0;
srcW = nextW;
srcH = nextH;
constraint = SkCanvas::kFast_SrcRectConstraint;
}
- auto result = sk_ref_sp(srcContext->asRenderTargetContext());
- SkASSERT(result);
- return result;
+ SkASSERT(currRTC);
+ return currRTC;
}
void GrRenderTargetContext::asyncRescaleAndReadPixels(
@@ -2001,24 +1988,13 @@
SkRect srcRectToDraw = SkRect::Make(srcRect);
// If the src is not texturable first try to make a copy to a texture.
if (!texProxy) {
- GrSurfaceDesc desc;
- desc.fWidth = srcRect.width();
- desc.fHeight = srcRect.height();
- desc.fConfig = fRenderTargetProxy->config();
- auto sContext = direct->priv().makeDeferredSurfaceContext(
- backendFormat, desc, this->origin(), GrMipMapped::kNo,
- SkBackingFit::kApprox, SkBudgeted::kNo,
- this->colorSpaceInfo().refColorSpace());
- if (!sContext) {
+ texProxy = GrSurfaceProxy::Copy(fContext, fRenderTargetProxy.get(),
+ GrMipMapped::kNo, srcRect, SkBackingFit::kApprox,
+ SkBudgeted::kNo);
+ if (!texProxy) {
callback(context, nullptr, 0);
return;
}
- if (!sContext->copy(fRenderTargetProxy.get(), srcRect, {0, 0})) {
- callback(context, nullptr, 0);
- return;
- }
- texProxy = sk_ref_sp(sContext->asTextureProxy());
- SkASSERT(texProxy);
srcRectToDraw = SkRect::MakeWH(srcRect.width(), srcRect.height());
}
rtc = direct->priv().makeDeferredRenderTargetContext(
@@ -2568,12 +2544,10 @@
GrSurfaceDesc desc;
bool rectsMustMatch = false;
bool disallowSubrect = false;
- GrSurfaceOrigin origin;
- if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &origin, &rectsMustMatch,
+ if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &rectsMustMatch,
&disallowSubrect)) {
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = rtProxy->config();
- origin = rtProxy->origin();
}
if (!disallowSubrect) {
@@ -2582,36 +2556,55 @@
SkIPoint dstPoint, dstOffset;
SkBackingFit fit;
+ GrSurfaceProxy::RectsMustMatch matchRects;
if (rectsMustMatch) {
desc.fWidth = rtProxy->width();
desc.fHeight = rtProxy->height();
dstPoint = {copyRect.fLeft, copyRect.fTop};
dstOffset = {0, 0};
fit = SkBackingFit::kExact;
+ matchRects = GrSurfaceProxy::RectsMustMatch::kYes;
} else {
desc.fWidth = copyRect.width();
desc.fHeight = copyRect.height();
dstPoint = {0, 0};
dstOffset = {copyRect.fLeft, copyRect.fTop};
fit = SkBackingFit::kApprox;
+ matchRects = GrSurfaceProxy::RectsMustMatch::kNo;
}
- SkASSERT(rtProxy->backendFormat().textureType() == GrTextureType::k2D);
- const GrBackendFormat& format = rtProxy->backendFormat();
- sk_sp<GrSurfaceContext> sContext = fContext->priv().makeDeferredSurfaceContext(
- format, desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes,
- sk_ref_sp(this->colorSpaceInfo().colorSpace()));
- if (!sContext) {
- SkDebugf("setupDstTexture: surfaceContext creation failed.\n");
- return false;
- }
+ sk_sp<GrTextureProxy> newProxy = GrSurfaceProxy::Copy(fContext, rtProxy, GrMipMapped::kNo,
+ copyRect, fit, SkBudgeted::kYes,
+ matchRects);
- if (!sContext->copy(rtProxy, copyRect, dstPoint)) {
- SkDebugf("setupDstTexture: copy failed.\n");
- return false;
- }
-
- dstProxy->setProxy(sContext->asTextureProxyRef());
+ dstProxy->setProxy(std::move(newProxy));
dstProxy->setOffset(dstOffset);
return true;
}
+
+bool GrRenderTargetContext::blitTexture(GrTextureProxy* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint) {
+ SkIRect clippedSrcRect;
+ SkIPoint clippedDstPoint;
+ if (!GrClipSrcRectAndDstPoint(this->asSurfaceProxy()->isize(), src->isize(), srcRect, dstPoint,
+ &clippedSrcRect, &clippedDstPoint)) {
+ return false;
+ }
+
+ GrPaint paint;
+ paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ auto fp = GrSimpleTextureEffect::Make(sk_ref_sp(src->asTextureProxy()),
+ SkMatrix::I());
+ if (!fp) {
+ return false;
+ }
+ paint.addColorFragmentProcessor(std::move(fp));
+
+ this->fillRectToRect(
+ GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
+ SkRect::MakeXYWH(clippedDstPoint.fX, clippedDstPoint.fY, clippedSrcRect.width(),
+ clippedSrcRect.height()),
+ SkRect::Make(clippedSrcRect));
+ return true;
+}
+
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 528a670..5e68e8d 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -397,6 +397,13 @@
const SkRect& dst);
/**
+ * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
+ * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
+ * respectively.
+ */
+ bool blitTexture(GrTextureProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
+
+ /**
* Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the
* command stream.
*/
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index 2b6987c..bedb5c3 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -5,6 +5,8 @@
* found in the LICENSE file.
*/
+#include "src/gpu/GrSurfaceContext.h"
+
#include "include/private/GrAuditTrail.h"
#include "include/private/GrOpList.h"
#include "include/private/GrRecordingContext.h"
@@ -15,7 +17,7 @@
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
-#include "src/gpu/GrSurfaceContext.h"
+#include "src/gpu/GrSurfaceContextPriv.h"
#include "src/gpu/GrSurfacePriv.h"
#include "src/gpu/GrTextureContext.h"
#include "src/gpu/SkGr.h"
@@ -371,7 +373,7 @@
}
auto tempProxy = direct->priv().proxyProvider()->createProxy(
- format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
+ format, desc, dstProxy->origin(), SkBackingFit::kApprox, SkBudgeted::kYes);
if (!tempProxy) {
return false;
}
@@ -393,7 +395,7 @@
}
if (this->asRenderTargetContext()) {
- std::unique_ptr<GrFragmentProcessor> fp;
+ std::unique_ptr<GrFragmentProcessor> fp;
if (canvas2DFastPath) {
fp = direct->priv().createUPMToPMEffect(
GrSimpleTextureEffect::Make(std::move(tempProxy), SkMatrix::I()));
@@ -415,10 +417,9 @@
} else {
SkIRect srcRect = SkIRect::MakeWH(width, height);
SkIPoint dstPoint = SkIPoint::Make(left, top);
- if (!caps->canCopySurface(this->asSurfaceProxy(), tempProxy.get(), srcRect, dstPoint)) {
+ if (this->copy(tempProxy.get(), srcRect, dstPoint)) {
return false;
}
- SkAssertResult(this->copy(tempProxy.get(), srcRect, dstPoint));
}
return true;
}
@@ -525,13 +526,17 @@
ASSERT_SINGLE_OWNER
RETURN_FALSE_IF_ABANDONED
SkDEBUGCODE(this->validate();)
- GR_AUDIT_TRAIL_AUTO_FRAME(this->auditTrail(), "GrSurfaceContext::copy");
+ GR_AUDIT_TRAIL_AUTO_FRAME(this->auditTrail(), "GrSurfaceContextPriv::copy");
- if (!fContext->priv().caps()->canCopySurface(this->asSurfaceProxy(), src, srcRect,
- dstPoint)) {
+ SkASSERT(src->backendFormat().textureType() != GrTextureType::kExternal);
+ SkASSERT(src->origin() == this->asSurfaceProxy()->origin());
+
+ GrSurfaceProxy* dst = this->asSurfaceProxy();
+
+ if (!this->fContext->priv().caps()->canCopySurface(dst, src, srcRect, dstPoint)) {
return false;
}
- return this->getOpList()->copySurface(fContext, this->asSurfaceProxy(),
- src, srcRect, dstPoint);
+ return this->getOpList()->copySurface(this->fContext, dst, src, srcRect, dstPoint);
}
+
diff --git a/src/gpu/GrSurfaceContext.h b/src/gpu/GrSurfaceContext.h
index 3cbb838..e72364c 100644
--- a/src/gpu/GrSurfaceContext.h
+++ b/src/gpu/GrSurfaceContext.h
@@ -39,26 +39,6 @@
int width() const { return this->asSurfaceProxy()->width(); }
int height() const { return this->asSurfaceProxy()->height(); }
- /*
- * Copy 'src' into the proxy backing this context
- * @param src src of pixels
- * @param srcRect the subset of 'src' to copy
- * @param dstPoint the origin of the 'srcRect' in the destination coordinate space
- * @return true if the copy succeeded; false otherwise
- *
- * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
- * Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
- * The end result is only valid src pixels and dst pixels will be touched but the copied
- * regions will not be shifted.
- */
- bool copy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
-
- bool copy(GrSurfaceProxy* src) {
- return this->copy(src,
- SkIRect::MakeWH(src->width(), src->height()),
- SkIPoint::Make(0, 0));
- }
-
/**
* These flags can be used with the read/write pixels functions below.
*/
@@ -134,6 +114,17 @@
GrSurfaceContextPriv surfPriv();
const GrSurfaceContextPriv surfPriv() const;
+#if GR_TEST_UTILS
+ bool testCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
+ return this->copy(src, srcRect, dstPoint);
+ }
+
+ bool testCopy(GrSurfaceProxy* src) {
+ return this->copy(src);
+ }
+#endif
+
+
protected:
friend class GrSurfaceContextPriv;
@@ -150,6 +141,29 @@
GrRecordingContext* fContext;
private:
+ friend class GrSurfaceProxy; // for copy
+
+ /**
+ * Copy 'src' into the proxy backing this context. This call will not do any draw fallback.
+ * Currently only writePixels and replaceRenderTarget call this directly. All other copies
+ * should go through GrSurfaceProxy::Copy.
+ * @param src src of pixels
+ * @param srcRect the subset of 'src' to copy
+ * @param dstPoint the origin of the 'srcRect' in the destination coordinate space
+ * @return true if the copy succeeded; false otherwise
+ *
+ * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
+ * Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
+ * The end result is only valid src pixels and dst pixels will be touched but the copied
+ * regions will not be shifted. The 'src' must have the same origin as the backing proxy
+ * of fSurfaceContext.
+ */
+ bool copy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
+
+ bool copy(GrSurfaceProxy* src) {
+ return this->copy(src, SkIRect::MakeWH(src->width(), src->height()), SkIPoint::Make(0, 0));
+ }
+
bool writePixelsImpl(GrContext* direct, int left, int top, int width, int height,
GrColorType srcColorType, SkColorSpace* srcColorSpace,
const void* srcBuffer, size_t srcRowBytes, uint32_t pixelOpsFlags);
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index f459e02..a699ec9 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -12,11 +12,13 @@
#include "include/private/GrOpList.h"
#include "include/private/GrRecordingContext.h"
#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrClip.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrGpuResourcePriv.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrSurfaceContext.h"
+#include "src/gpu/GrSurfaceContextPriv.h"
#include "src/gpu/GrSurfacePriv.h"
#include "src/gpu/GrTexturePriv.h"
#include "src/gpu/GrTextureRenderTargetProxy.h"
@@ -335,33 +337,56 @@
GrMipMapped mipMapped,
SkIRect srcRect,
SkBackingFit fit,
- SkBudgeted budgeted) {
+ SkBudgeted budgeted,
+ RectsMustMatch rectsMustMatch) {
SkASSERT(LazyState::kFully != src->lazyInstantiationState());
+ GrSurfaceDesc dstDesc;
+ dstDesc.fConfig = src->config();
+
+ SkIPoint dstPoint;
+ if (rectsMustMatch == RectsMustMatch::kYes) {
+ dstDesc.fWidth = src->width();
+ dstDesc.fHeight = src->height();
+ dstPoint = {srcRect.fLeft, srcRect.fTop};
+ } else {
+ dstDesc.fWidth = srcRect.width();
+ dstDesc.fHeight = srcRect.height();
+ dstPoint = {0, 0};
+ }
+
if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
return nullptr;
}
- GrSurfaceDesc dstDesc;
- dstDesc.fWidth = srcRect.width();
- dstDesc.fHeight = srcRect.height();
- dstDesc.fConfig = src->config();
-
- GrBackendFormat format = src->backendFormat().makeTexture2D();
- if (!format.isValid()) {
- return nullptr;
+ if (src->backendFormat().textureType() != GrTextureType::kExternal) {
+ sk_sp<GrSurfaceContext> dstContext(context->priv().makeDeferredSurfaceContext(
+ src->backendFormat().makeTexture2D(), dstDesc, src->origin(), mipMapped, fit,
+ budgeted));
+ if (!dstContext) {
+ return nullptr;
+ }
+ if (context->priv().caps()->canCopySurface(src, dstContext->asSurfaceProxy(), srcRect,
+ dstPoint)) {
+ SkAssertResult(dstContext->copy(std::move(src), srcRect, dstPoint));
+ return dstContext->asTextureProxyRef();
+ }
}
+ if (src->asTextureProxy()) {
+ GrBackendFormat format = src->backendFormat().makeTexture2D();
+ if (!format.isValid()) {
+ return nullptr;
+ }
- sk_sp<GrSurfaceContext> dstContext(context->priv().makeDeferredSurfaceContext(
- format, dstDesc, src->origin(), mipMapped, fit, budgeted));
- if (!dstContext) {
- return nullptr;
+ sk_sp<GrRenderTargetContext> dstContext = context->priv().makeDeferredRenderTargetContext(
+ format, fit, dstDesc.fWidth, dstDesc.fHeight, dstDesc.fConfig, nullptr, 1,
+ mipMapped, src->origin(), nullptr, budgeted);
+
+ if (dstContext && dstContext->blitTexture(src->asTextureProxy(), srcRect, dstPoint)) {
+ return dstContext->asTextureProxyRef();
+ }
}
-
- if (!dstContext->copy(src, srcRect, SkIPoint::Make(0, 0))) {
- return nullptr;
- }
-
- return dstContext->asTextureProxyRef();
+ // Can't use backend copies or draws.
+ return nullptr;
}
sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrRecordingContext* context, GrSurfaceProxy* src,
@@ -372,29 +397,6 @@
budgeted);
}
-sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrRecordingContext* context,
- const GrSurfaceDesc& dstDesc,
- GrSurfaceOrigin origin, GrSurfaceProxy* srcProxy) {
- SkASSERT(LazyState::kFully != srcProxy->lazyInstantiationState());
-
- GrBackendFormat format = srcProxy->backendFormat().makeTexture2D();
- if (!format.isValid()) {
- return nullptr;
- }
-
- sk_sp<GrSurfaceContext> dstContext(context->priv().makeDeferredSurfaceContext(
- format, dstDesc, origin, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes));
- if (!dstContext) {
- return nullptr;
- }
-
- if (!dstContext->copy(srcProxy)) {
- return nullptr;
- }
-
- return dstContext;
-}
-
void GrSurfaceProxyPriv::exactify() {
SkASSERT(GrSurfaceProxy::LazyState::kFully != fProxy->lazyInstantiationState());
if (this->isExact()) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index c10b696..a2b45fd 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -254,7 +254,11 @@
if (this->context()->abandoned()) {
return;
}
- rtc->copy(fRenderTargetContext->asSurfaceProxy());
+
+ SkASSERT(fRenderTargetContext->asTextureProxy());
+ SkAssertResult(rtc->blitTexture(fRenderTargetContext->asTextureProxy(),
+ SkIRect::MakeWH(this->width(), this->height()),
+ SkIPoint::Make(0,0)));
}
fRenderTargetContext = std::move(rtc);
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 5f0e9dc..27a1669 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -133,31 +133,8 @@
return nullptr;
}
- GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
- GrSurfaceDesc desc;
- desc.fFlags = kNone_GrSurfaceFlags;
- desc.fWidth = baseProxy->width();
- desc.fHeight = baseProxy->height();
- desc.fConfig = baseProxy->config();
- desc.fSampleCnt = 1;
-
- GrBackendFormat format = baseProxy->backendFormat().makeTexture2D();
- if (!format.isValid()) {
- return nullptr;
- }
-
- sk_sp<GrTextureProxy> proxy =
- proxyProvider->createMipMapProxy(format, desc, baseProxy->origin(), SkBudgeted::kYes);
- if (!proxy) {
- return nullptr;
- }
-
- // Copy the base layer to our proxy
- sk_sp<GrSurfaceContext> sContext = ctx->priv().makeWrappedSurfaceContext(proxy);
- SkASSERT(sContext);
- SkAssertResult(sContext->copy(baseProxy));
-
- return proxy;
+ return GrSurfaceProxy::Copy(ctx, baseProxy, GrMipMapped::kYes, SkBackingFit::kExact,
+ SkBudgeted::kYes);
}
sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrRecordingContext* ctx,
diff --git a/src/gpu/geometry/GrRect.h b/src/gpu/geometry/GrRect.h
index 064d539..2a3e72b 100644
--- a/src/gpu/geometry/GrRect.h
+++ b/src/gpu/geometry/GrRect.h
@@ -82,4 +82,60 @@
SkMatrix rectTransform = SkMatrix::MakeRectToRect(inRect, outRect, SkMatrix::kFill_ScaleToFit);
rectTransform.mapPoints(outPts, inPts, ptCount);
}
+
+/**
+ * Clips the srcRect and the dstPoint to the bounds of the srcSize and dstSize respectively. Returns
+ * true if the srcRect and dstRect intersect the srcRect and dst rect (dstPoint with srcRect
+ * width/height). Returns false otherwise. The clipped values are returned in clippedSrcRect and
+ * clippedDstPoint.
+ */
+static inline bool GrClipSrcRectAndDstPoint(const SkISize& dstSize,
+ const SkISize& srcSize,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint,
+ SkIRect* clippedSrcRect,
+ SkIPoint* clippedDstPoint) {
+ *clippedSrcRect = srcRect;
+ *clippedDstPoint = dstPoint;
+
+ // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
+ if (clippedSrcRect->fLeft < 0) {
+ clippedDstPoint->fX -= clippedSrcRect->fLeft;
+ clippedSrcRect->fLeft = 0;
+ }
+ if (clippedDstPoint->fX < 0) {
+ clippedSrcRect->fLeft -= clippedDstPoint->fX;
+ clippedDstPoint->fX = 0;
+ }
+
+ // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
+ if (clippedSrcRect->fTop < 0) {
+ clippedDstPoint->fY -= clippedSrcRect->fTop;
+ clippedSrcRect->fTop = 0;
+ }
+ if (clippedDstPoint->fY < 0) {
+ clippedSrcRect->fTop -= clippedDstPoint->fY;
+ clippedDstPoint->fY = 0;
+ }
+
+ // clip the right edge to the src and dst bounds.
+ if (clippedSrcRect->fRight > srcSize.width()) {
+ clippedSrcRect->fRight = srcSize.width();
+ }
+ if (clippedDstPoint->fX + clippedSrcRect->width() > dstSize.width()) {
+ clippedSrcRect->fRight = clippedSrcRect->fLeft + dstSize.width() - clippedDstPoint->fX;
+ }
+
+ // clip the bottom edge to the src and dst bounds.
+ if (clippedSrcRect->fBottom > srcSize.height()) {
+ clippedSrcRect->fBottom = srcSize.height();
+ }
+ if (clippedDstPoint->fY + clippedSrcRect->height() > dstSize.height()) {
+ clippedSrcRect->fBottom = clippedSrcRect->fTop + dstSize.height() - clippedDstPoint->fY;
+ }
+
+ // The above clipping steps may have inverted the rect if it didn't intersect either the src or
+ // dst bounds.
+ return !clippedSrcRect->isEmpty();
+}
#endif
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index ae59460..8251ec3 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2308,11 +2308,9 @@
}
bool GrGLCaps::canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
- bool dstIsTextureable, bool dstIsGLTexture2D,
- GrSurfaceOrigin dstOrigin,
+ const GrTextureType* dstTypeIfTexture,
GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
- bool srcIsTextureable, bool srcIsGLTexture2D,
- GrSurfaceOrigin srcOrigin) const {
+ const GrTextureType* srcTypeIfTexture) const {
// Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
// and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
// many drivers would allow it to work, but ANGLE does not.
@@ -2328,16 +2326,15 @@
// CopyTex(Sub)Image writes to a texture and we have no way of dynamically wrapping a RT in a
// texture.
- if (!dstIsTextureable) {
+ if (!dstTypeIfTexture) {
return false;
}
- // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D, that no mirroring
- // is required
+ // Check that we could wrap the source in an FBO, that the dst is not TEXTURE_EXTERNAL, that no
+ // mirroring is required
if (this->canConfigBeFBOColorAttachment(srcConfig) &&
- (!srcIsTextureable || srcIsGLTexture2D) &&
- dstIsGLTexture2D &&
- dstOrigin == srcOrigin) {
+ (!srcTypeIfTexture || *srcTypeIfTexture != GrTextureType::kExternal) &&
+ *dstTypeIfTexture != GrTextureType::kExternal) {
return true;
} else {
return false;
@@ -2345,11 +2342,10 @@
}
bool GrGLCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
- bool dstIsTextureable, bool dstIsGLTexture2D,
- GrSurfaceOrigin dstOrigin,
+ const GrTextureType* dstTypeIfTexture,
GrPixelConfig srcConfig, int srcSampleCnt,
- bool srcIsTextureable, bool srcIsGLTexture2D,
- GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
+ const GrTextureType* srcTypeIfTexture,
+ const SkRect& srcBounds, bool srcBoundsExact,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
auto blitFramebufferFlags = this->blitFramebufferSupportFlags();
if (!this->canConfigBeFBOColorAttachment(dstConfig) ||
@@ -2357,30 +2353,23 @@
return false;
}
- if (dstIsTextureable && !dstIsGLTexture2D) {
+ if (dstTypeIfTexture && *dstTypeIfTexture == GrTextureType::kExternal) {
return false;
}
- if (srcIsTextureable && !srcIsGLTexture2D) {
+ if (srcTypeIfTexture && *srcTypeIfTexture == GrTextureType::kExternal) {
return false;
}
if (GrGLCaps::kNoSupport_BlitFramebufferFlag & blitFramebufferFlags) {
return false;
}
- if (GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag & blitFramebufferFlags) {
- // We would mirror to compensate for origin changes. Note that copySurface is
- // specified such that the src and dst rects are the same.
- if (dstOrigin != srcOrigin) {
- return false;
- }
- }
if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & blitFramebufferFlags) {
if (srcSampleCnt > 1) {
if (1 == dstSampleCnt) {
return false;
}
- if (SkRect::Make(srcRect) != srcBounds) {
+ if (SkRect::Make(srcRect) != srcBounds || !srcBoundsExact) {
return false;
}
}
@@ -2407,18 +2396,11 @@
if (dstPoint.fX != srcRect.fLeft || dstPoint.fY != srcRect.fTop) {
return false;
}
- if (dstOrigin != srcOrigin) {
- return false;
- }
}
}
return true;
}
-bool GrGLCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const {
- return this->canConfigBeFBOColorAttachment(dstConfig) && srcIsTextureable;
-}
-
static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& glCaps) {
const GrRenderTargetProxy* rt = surf->asRenderTargetProxy();
if (!rt) {
@@ -2435,9 +2417,6 @@
bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
- GrSurfaceOrigin dstOrigin = dst->origin();
- GrSurfaceOrigin srcOrigin = src->origin();
-
GrPixelConfig dstConfig = dst->config();
GrPixelConfig srcConfig = src->config();
@@ -2452,8 +2431,7 @@
SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
- // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
- // swizzle.
+ // None of our copy methods can handle a swizzle.
if (this->shaderCaps()->configOutputSwizzle(src->config()) !=
this->shaderCaps()->configOutputSwizzle(dst->config())) {
return false;
@@ -2462,37 +2440,28 @@
const GrTextureProxy* dstTex = dst->asTextureProxy();
const GrTextureProxy* srcTex = src->asTextureProxy();
- bool dstIsTex2D = dstTex ? (dstTex->textureType() == GrTextureType::k2D) : false;
- bool srcIsTex2D = srcTex ? (srcTex->textureType() == GrTextureType::k2D) : false;
-
- // One of the possible requirements for copy as blit is that the srcRect must match the bounds
- // of the src surface. If we have a approx fit surface we can't know for sure what the src
- // bounds will be at this time. Thus we assert that if we say we can copy as blit and the src is
- // approx that we also can copy as draw. Therefore when it comes time to do the copy we will
- // know we will at least be able to do it as a draw.
-#ifdef SK_DEBUG
- if (this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
- dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
- srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint) &&
- !src->priv().isExact()) {
- SkASSERT(this->canCopyAsDraw(dstConfig, SkToBool(srcTex)));
+ GrTextureType dstTexType;
+ GrTextureType* dstTexTypePtr = nullptr;
+ GrTextureType srcTexType;
+ GrTextureType* srcTexTypePtr = nullptr;
+ if (dstTex) {
+ dstTexType = dstTex->textureType();
+ dstTexTypePtr = &dstTexType;
}
-#endif
+ if (srcTex) {
+ srcTexType = srcTex->textureType();
+ srcTexTypePtr = &srcTexType;
+ }
- return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this),
- SkToBool(dstTex), dstIsTex2D, dstOrigin,
- srcConfig, has_msaa_render_buffer(src, *this),
- SkToBool(srcTex), srcIsTex2D, srcOrigin) ||
- this->canCopyAsBlit(dstConfig, dstSampleCnt, SkToBool(dstTex),
- dstIsTex2D, dstOrigin, srcConfig, srcSampleCnt, SkToBool(srcTex),
- srcIsTex2D, srcOrigin, src->getBoundsRect(), srcRect,
- dstPoint) ||
- this->canCopyAsDraw(dstConfig, SkToBool(srcTex));
+ return this->canCopyTexSubImage(dstConfig, has_msaa_render_buffer(dst, *this), dstTexTypePtr,
+ srcConfig, has_msaa_render_buffer(src, *this), srcTexTypePtr) ||
+ this->canCopyAsBlit(dstConfig, dstSampleCnt, dstTexTypePtr, srcConfig, srcSampleCnt,
+ srcTexTypePtr, src->getBoundsRect(), src->priv().isExact(),
+ srcRect, dstPoint);
}
bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
- GrSurfaceOrigin* origin, bool* rectsMustMatch,
- bool* disallowSubrect) const {
+ bool* rectsMustMatch, bool* disallowSubrect) const {
// By default, we don't require rects to match.
*rectsMustMatch = false;
@@ -2502,7 +2471,6 @@
// If the src is a texture, we can implement the blit as a draw assuming the config is
// renderable.
if (src->asTextureProxy() && !this->isConfigRenderable(src->config())) {
- *origin = kBottomLeft_GrSurfaceOrigin;
desc->fFlags = kRenderTarget_GrSurfaceFlag;
desc->fConfig = src->config();
return true;
@@ -2523,7 +2491,6 @@
// possible and we return false to fallback to creating a render target dst for render-to-
// texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
// creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
- GrSurfaceOrigin originForBlitFramebuffer = kTopLeft_GrSurfaceOrigin;
bool rectsMustMatchForBlitFramebuffer = false;
bool disallowSubrectForBlitFramebuffer = false;
if (src->numColorSamples() > 1 &&
@@ -2531,14 +2498,9 @@
rectsMustMatchForBlitFramebuffer = true;
disallowSubrectForBlitFramebuffer = true;
// Mirroring causes rects to mismatch later, don't allow it.
- originForBlitFramebuffer = src->origin();
} else if (src->numColorSamples() > 1 && (this->blitFramebufferSupportFlags() &
kRectsMustMatchForMSAASrc_BlitFramebufferFlag)) {
rectsMustMatchForBlitFramebuffer = true;
- // Mirroring causes rects to mismatch later, don't allow it.
- originForBlitFramebuffer = src->origin();
- } else if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
- originForBlitFramebuffer = src->origin();
}
// Check for format issues with glCopyTexSubImage2D
@@ -2546,7 +2508,6 @@
// glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
// then we set up for that, otherwise fail.
if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
- *origin = originForBlitFramebuffer;
desc->fConfig = kBGRA_8888_GrPixelConfig;
*rectsMustMatch = rectsMustMatchForBlitFramebuffer;
*disallowSubrect = disallowSubrectForBlitFramebuffer;
@@ -2562,7 +2523,6 @@
// It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO
// blit or fail.
if (this->canConfigBeFBOColorAttachment(src->config())) {
- *origin = originForBlitFramebuffer;
desc->fConfig = src->config();
*rectsMustMatch = rectsMustMatchForBlitFramebuffer;
*disallowSubrect = disallowSubrectForBlitFramebuffer;
@@ -2573,7 +2533,6 @@
}
// We'll do a CopyTexSubImage. Make the dst a plain old texture.
- *origin = src->origin();
desc->fConfig = src->config();
desc->fFlags = kNone_GrSurfaceFlags;
return true;
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index a2e2948..77eed27 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -388,21 +388,17 @@
}
bool canCopyTexSubImage(GrPixelConfig dstConfig, bool dstHasMSAARenderBuffer,
- bool dstIsTextureable, bool dstIsGLTexture2D,
- GrSurfaceOrigin dstOrigin,
+ const GrTextureType* dstTypeIfTexture,
GrPixelConfig srcConfig, bool srcHasMSAARenderBuffer,
- bool srcIsTextureable, bool srcIsGLTexture2D,
- GrSurfaceOrigin srcOrigin) const;
+ const GrTextureType* srcTypeIfTexture) const;
bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt,
- bool dstIsTextureable, bool dstIsGLTexture2D,
- GrSurfaceOrigin dstOrigin,
+ const GrTextureType* dstTypeIfTexture,
GrPixelConfig srcConfig, int srcSampleCnt,
- bool srcIsTextureable, bool srcIsGLTexture2D,
- GrSurfaceOrigin srcOrigin, const SkRect& srcBounds,
+ const GrTextureType* srcTypeIfTexture,
+ const SkRect& srcBounds, bool srcBoundsExact,
const SkIRect& srcRect, const SkIPoint& dstPoint) const;
- bool canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const;
- bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
+ bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
bool* rectsMustMatch, bool* disallowSubrect) const override;
bool programBinarySupport() const { return fProgramBinarySupport; }
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index a899eb0..d670a12 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3180,12 +3180,11 @@
}
// Determines whether glBlitFramebuffer could be used between src and dst by onCopySurface.
-static inline bool can_blit_framebuffer_for_copy_surface(
- const GrSurface* dst, GrSurfaceOrigin dstOrigin,
- const GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint,
- const GrGLCaps& caps) {
+static inline bool can_blit_framebuffer_for_copy_surface(const GrSurface* dst,
+ const GrSurface* src,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint,
+ const GrGLCaps& caps) {
int dstSampleCnt = 0;
int srcSampleCnt = 0;
if (const GrRenderTarget* rt = dst->asRenderTarget()) {
@@ -3200,12 +3199,22 @@
const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture());
const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture());
- bool dstIsGLTexture2D = dstTex ? GR_GL_TEXTURE_2D == dstTex->target() : false;
- bool srcIsGLTexture2D = srcTex ? GR_GL_TEXTURE_2D == srcTex->target() : false;
+ GrTextureType dstTexType;
+ GrTextureType* dstTexTypePtr = nullptr;
+ GrTextureType srcTexType;
+ GrTextureType* srcTexTypePtr = nullptr;
+ if (dstTex) {
+ dstTexType = dstTex->texturePriv().textureType();
+ dstTexTypePtr = &dstTexType;
+ }
+ if (srcTex) {
+ srcTexType = srcTex->texturePriv().textureType();
+ srcTexTypePtr = &srcTexType;
+ }
- return caps.canCopyAsBlit(dst->config(), dstSampleCnt, SkToBool(dstTex), dstIsGLTexture2D,
- dstOrigin, src->config(), srcSampleCnt, SkToBool(srcTex),
- srcIsGLTexture2D, srcOrigin, src->getBoundsRect(), srcRect, dstPoint);
+ return caps.canCopyAsBlit(dst->config(), dstSampleCnt, dstTexTypePtr,
+ src->config(), srcSampleCnt, srcTexTypePtr,
+ src->getBoundsRect(), true, srcRect, dstPoint);
}
static bool rt_has_msaa_render_buffer(const GrGLRenderTarget* rt, const GrGLCaps& glCaps) {
@@ -3216,8 +3225,7 @@
return rt->numColorSamples() > 1 && glCaps.usesMSAARenderBuffers() && rt->renderFBOID() != 0;
}
-static inline bool can_copy_texsubimage(const GrSurface* dst, GrSurfaceOrigin dstOrigin,
- const GrSurface* src, GrSurfaceOrigin srcOrigin,
+static inline bool can_copy_texsubimage(const GrSurface* dst, const GrSurface* src,
const GrGLCaps& caps) {
const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
@@ -3228,13 +3236,21 @@
bool dstHasMSAARenderBuffer = dstRT ? rt_has_msaa_render_buffer(dstRT, caps) : false;
bool srcHasMSAARenderBuffer = srcRT ? rt_has_msaa_render_buffer(srcRT, caps) : false;
- bool dstIsGLTexture2D = dstTex ? GR_GL_TEXTURE_2D == dstTex->target() : false;
- bool srcIsGLTexture2D = srcTex ? GR_GL_TEXTURE_2D == srcTex->target() : false;
+ GrTextureType dstTexType;
+ GrTextureType* dstTexTypePtr = nullptr;
+ GrTextureType srcTexType;
+ GrTextureType* srcTexTypePtr = nullptr;
+ if (dstTex) {
+ dstTexType = dstTex->texturePriv().textureType();
+ dstTexTypePtr = &dstTexType;
+ }
+ if (srcTex) {
+ srcTexType = srcTex->texturePriv().textureType();
+ srcTexTypePtr = &srcTexType;
+ }
- return caps.canCopyTexSubImage(dst->config(), dstHasMSAARenderBuffer, SkToBool(dstTex),
- dstIsGLTexture2D, dstOrigin, src->config(),
- srcHasMSAARenderBuffer, SkToBool(srcTex), srcIsGLTexture2D,
- srcOrigin);
+ return caps.canCopyTexSubImage(dst->config(), dstHasMSAARenderBuffer, dstTexTypePtr,
+ src->config(), srcHasMSAARenderBuffer, srcTexTypePtr);
}
// If a temporary FBO was created, its non-zero ID is returned.
@@ -3325,162 +3341,26 @@
}
}
-bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) {
- // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
- // swizzle.
+bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) {
+ // None of our copy methods can handle a swizzle.
if (this->caps()->shaderCaps()->configOutputSwizzle(src->config()) !=
this->caps()->shaderCaps()->configOutputSwizzle(dst->config())) {
return false;
}
- // Don't prefer copying as a draw if the dst doesn't already have a FBO object.
- // This implicitly handles this->glCaps().useDrawInsteadOfAllRenderTargetWrites().
- bool preferCopy = SkToBool(dst->asRenderTarget());
- if (preferCopy && this->glCaps().canCopyAsDraw(dst->config(), SkToBool(src->asTexture()))) {
- if (this->copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) {
- return true;
- }
- }
- if (can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this->glCaps())) {
- this->copySurfaceAsCopyTexSubImage(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
+ if (can_copy_texsubimage(dst, src, this->glCaps())) {
+ this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
return true;
}
- if (can_blit_framebuffer_for_copy_surface(dst, dstOrigin, src, srcOrigin,
- srcRect, dstPoint, this->glCaps())) {
- return this->copySurfaceAsBlitFramebuffer(dst, dstOrigin, src, srcOrigin,
- srcRect, dstPoint);
- }
-
- if (!preferCopy && this->glCaps().canCopyAsDraw(dst->config(), SkToBool(src->asTexture()))) {
- if (this->copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) {
- return true;
- }
+ if (can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this->glCaps())) {
+ return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
}
return false;
}
-bool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
- TRACE_EVENT0("skia", TRACE_FUNC);
-
- int progIdx = TextureToCopyProgramIdx(srcTex);
- const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
- GrSLType samplerType =
- GrSLCombinedSamplerTypeForTextureType(srcTex->texturePriv().textureType());
-
- if (!fCopyProgramArrayBuffer) {
- static const GrGLfloat vdata[] = {
- 0, 0,
- 0, 1,
- 1, 0,
- 1, 1
- };
- fCopyProgramArrayBuffer = GrGLBuffer::Make(this, sizeof(vdata), GrGpuBufferType::kVertex,
- kStatic_GrAccessPattern, vdata);
- }
- if (!fCopyProgramArrayBuffer) {
- return false;
- }
-
- SkASSERT(!fCopyPrograms[progIdx].fProgram);
- GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram());
- if (!fCopyPrograms[progIdx].fProgram) {
- return false;
- }
-
- const char* version = shaderCaps->versionDeclString();
- GrShaderVar aVertex("a_vertex", kHalf2_GrSLType, GrShaderVar::kIn_TypeModifier);
- GrShaderVar uTexCoordXform("u_texCoordXform", kHalf4_GrSLType,
- GrShaderVar::kUniform_TypeModifier);
- GrShaderVar uPosXform("u_posXform", kHalf4_GrSLType, GrShaderVar::kUniform_TypeModifier);
- GrShaderVar uTexture("u_texture", samplerType, GrShaderVar::kUniform_TypeModifier);
- GrShaderVar vTexCoord("v_texCoord", kHalf2_GrSLType, GrShaderVar::kOut_TypeModifier);
- GrShaderVar oFragColor("o_FragColor", kHalf4_GrSLType, GrShaderVar::kOut_TypeModifier);
-
- SkString vshaderTxt(version);
- if (shaderCaps->noperspectiveInterpolationSupport()) {
- if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
- vshaderTxt.appendf("#extension %s : require\n", extension);
- }
- vTexCoord.addModifier("noperspective");
- }
-
- aVertex.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
- uTexCoordXform.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
- uPosXform.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
- vTexCoord.appendDecl(shaderCaps, &vshaderTxt);
- vshaderTxt.append(";");
-
- vshaderTxt.append(
- "// Copy Program VS\n"
- "void main() {"
- " v_texCoord = half2(a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw);"
- " sk_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
- " sk_Position.zw = half2(0, 1);"
- "}"
- );
-
- SkString fshaderTxt(version);
- if (shaderCaps->noperspectiveInterpolationSupport()) {
- if (const char* extension = shaderCaps->noperspectiveInterpolationExtensionString()) {
- fshaderTxt.appendf("#extension %s : require\n", extension);
- }
- }
- vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier);
- vTexCoord.appendDecl(shaderCaps, &fshaderTxt);
- fshaderTxt.append(";");
- uTexture.appendDecl(shaderCaps, &fshaderTxt);
- fshaderTxt.append(";");
- fshaderTxt.appendf(
- "// Copy Program FS\n"
- "void main() {"
- " sk_FragColor = texture(u_texture, v_texCoord);"
- "}"
- );
-
- auto errorHandler = this->getContext()->priv().getShaderErrorHandler();
- SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
- SkSL::Program::Settings settings;
- settings.fCaps = shaderCaps;
- SkSL::String glsl;
- std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(*fGLContext, SkSL::Program::kVertex_Kind,
- sksl, settings, &glsl, errorHandler);
- GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
- GR_GL_VERTEX_SHADER, glsl, &fStats, errorHandler);
- SkASSERT(program->fInputs.isEmpty());
-
- sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
- program = GrSkSLtoGLSL(*fGLContext, SkSL::Program::kFragment_Kind, sksl, settings, &glsl,
- errorHandler);
- GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
- GR_GL_FRAGMENT_SHADER, glsl, &fStats,
- errorHandler);
- SkASSERT(program->fInputs.isEmpty());
-
- GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram));
-
- GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform,
- GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture"));
- GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform,
- GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform"));
- GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform,
- GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform"));
-
- GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex"));
-
- GL_CALL(DeleteShader(vshader));
- GL_CALL(DeleteShader(fshader));
-
- return true;
-}
-
bool GrGLGpu::createMipmapProgram(int progIdx) {
const bool oddWidth = SkToBool(progIdx & 0x2);
const bool oddHeight = SkToBool(progIdx & 0x1);
@@ -3634,134 +3514,30 @@
return true;
}
-bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint) {
- GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
- int progIdx = TextureToCopyProgramIdx(srcTex);
-
- if (!this->glCaps().canConfigBeFBOColorAttachment(dst->config())) {
- return false;
- }
-
- if (!fCopyPrograms[progIdx].fProgram) {
- if (!this->createCopyProgram(srcTex)) {
- SkDebugf("Failed to create copy program.\n");
- return false;
- }
- }
-
- int w = srcRect.width();
- int h = srcRect.height();
-
- this->bindTexture(0, GrSamplerState::ClampNearest(), srcTex);
-
- this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, kDst_TempFBOTarget);
- this->flushViewport(dst->width(), dst->height());
- fHWBoundRenderTargetUniqueID.makeInvalid();
-
- SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
-
- this->flushProgram(fCopyPrograms[progIdx].fProgram);
-
- fHWVertexArrayState.setVertexArrayID(this, 0);
-
- GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
- attribs->enableVertexArrays(this, 1);
- attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kFloat2_GrVertexAttribType,
- kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
-
- // dst rect edges in NDC (-1 to 1)
- int dw = dst->width();
- int dh = dst->height();
- GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
- GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
- GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
- GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
- if (kBottomLeft_GrSurfaceOrigin == dstOrigin) {
- dy0 = -dy0;
- dy1 = -dy1;
- }
-
- GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft;
- GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w);
- GrGLfloat sy0 = (GrGLfloat)srcRect.fTop;
- GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h);
- int sw = src->width();
- int sh = src->height();
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- sy0 = sh - sy0;
- sy1 = sh - sy1;
- }
- if (srcTex->texturePriv().textureType() != GrTextureType::kRectangle) {
- // src rect edges in normalized texture space (0 to 1)
- sx0 /= sw;
- sx1 /= sw;
- sy0 /= sh;
- sy1 /= sh;
- }
-
- GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
- GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
- sx1 - sx0, sy1 - sy0, sx0, sy0));
- GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0));
-
- GrXferProcessor::BlendInfo blendInfo;
- blendInfo.reset();
- this->flushBlend(blendInfo, GrSwizzle::RGBA());
- this->flushColorWrite(true);
- this->flushHWAAState(nullptr, false);
- this->disableScissor();
- this->disableWindowRectangles();
- this->disableStencil();
- if (this->glCaps().srgbWriteControl()) {
- this->flushFramebufferSRGB(true);
- }
-
- GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
- this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst);
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
-
- return true;
-}
-
-void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
+void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
- SkASSERT(can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this->glCaps()));
+ SkASSERT(can_copy_texsubimage(dst, src, this->glCaps()));
this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, kSrc_TempFBOTarget);
GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture());
SkASSERT(dstTex);
// We modified the bound FBO
fHWBoundRenderTargetUniqueID.makeInvalid();
- GrGLIRect srcGLRect;
- srcGLRect.setRelativeTo(src->height(), srcRect, srcOrigin);
this->bindTextureToScratchUnit(dstTex->target(), dstTex->textureID());
- GrGLint dstY;
- if (kBottomLeft_GrSurfaceOrigin == dstOrigin) {
- dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
- } else {
- dstY = dstPoint.fY;
- }
GL_CALL(CopyTexSubImage2D(dstTex->target(), 0,
- dstPoint.fX, dstY,
- srcGLRect.fLeft, srcGLRect.fBottom,
- srcGLRect.fWidth, srcGLRect.fHeight));
+ dstPoint.fX, dstPoint.fY,
+ srcRect.fLeft, srcRect.fTop,
+ srcRect.width(), srcRect.height()));
this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, src);
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
srcRect.width(), srcRect.height());
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
+ // The rect is already in device space so we pass in kTopLeft so no flip is done.
+ this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
}
-bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
+bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
- SkASSERT(can_blit_framebuffer_for_copy_surface(dst, dstOrigin, src, srcOrigin,
- srcRect, dstPoint, this->glCaps()));
+ SkASSERT(can_blit_framebuffer_for_copy_surface(dst, src, srcRect, dstPoint, this->glCaps()));
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
srcRect.width(), srcRect.height());
if (dst == src) {
@@ -3774,37 +3550,25 @@
this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, kSrc_TempFBOTarget);
// We modified the bound FBO
fHWBoundRenderTargetUniqueID.makeInvalid();
- GrGLIRect srcGLRect;
- GrGLIRect dstGLRect;
- srcGLRect.setRelativeTo(src->height(), srcRect, srcOrigin);
- dstGLRect.setRelativeTo(dst->height(), dstRect, dstOrigin);
// BlitFrameBuffer respects the scissor, so disable it.
this->disableScissor();
this->disableWindowRectangles();
- GrGLint srcY0;
- GrGLint srcY1;
- // Does the blit need to y-mirror or not?
- if (srcOrigin == dstOrigin) {
- srcY0 = srcGLRect.fBottom;
- srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
- } else {
- srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
- srcY1 = srcGLRect.fBottom;
- }
- GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
- srcY0,
- srcGLRect.fLeft + srcGLRect.fWidth,
- srcY1,
- dstGLRect.fLeft,
- dstGLRect.fBottom,
- dstGLRect.fLeft + dstGLRect.fWidth,
- dstGLRect.fBottom + dstGLRect.fHeight,
+ GL_CALL(BlitFramebuffer(srcRect.fLeft,
+ srcRect.fTop,
+ srcRect.fRight,
+ srcRect.fBottom,
+ dstRect.fLeft,
+ dstRect.fTop,
+ dstRect.fRight,
+ dstRect.fBottom,
GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
this->unbindTextureFBOForPixelOps(GR_GL_DRAW_FRAMEBUFFER, dst);
this->unbindTextureFBOForPixelOps(GR_GL_READ_FRAMEBUFFER, src);
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
+
+ // The rect is already in device space so we pass in kTopLeft so no flip is done.
+ this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
return true;
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 5a6c6d8..6b19022 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -255,10 +255,8 @@
bool onRegenerateMipMapLevels(GrTexture*) override;
- bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) override;
+ bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override;
// binds texture unit in GL
void setTextureUnit(int unitIdx);
@@ -301,15 +299,12 @@
bool waitSync(GrGLsync, uint64_t timeout, bool flush);
- bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint);
- void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint);
- bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint);
+ bool copySurfaceAsDraw(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint);
+ void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint);
+ bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint);
static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
@@ -430,7 +425,6 @@
void onDumpJSON(SkJSONWriter*) const override;
#endif
- bool createCopyProgram(GrTexture* srcTexture);
bool createMipmapProgram(int progIdx);
std::unique_ptr<GrGLContext> fGLContext;
diff --git a/src/gpu/gl/GrGLGpuCommandBuffer.h b/src/gpu/gl/GrGLGpuCommandBuffer.h
index 0f9370f..0ec79c6 100644
--- a/src/gpu/gl/GrGLGpuCommandBuffer.h
+++ b/src/gpu/gl/GrGLGpuCommandBuffer.h
@@ -21,9 +21,8 @@
public:
GrGLGpuTextureCommandBuffer(GrGLGpu* gpu) : fGpu(gpu) {}
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override {
- fGpu->copySurface(fTexture, fOrigin, src, srcOrigin, srcRect, dstPoint);
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override {
+ fGpu->copySurface(fTexture, src, srcRect, dstPoint);
}
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
@@ -68,9 +67,8 @@
state->doUpload(upload);
}
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override {
- fGpu->copySurface(fRenderTarget, fOrigin, src, srcOrigin, srcRect, dstPoint);
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override {
+ fGpu->copySurface(fRenderTarget, src,srcRect, dstPoint);
}
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index b8059d3..c3806d1 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -70,7 +70,7 @@
bool surfaceSupportsReadPixels(const GrSurface*) const override { return true; }
- bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
+ bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
bool* rectsMustMatch, bool* disallowSubrect) const override {
return false;
}
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index cf49972..de3af71 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -101,8 +101,7 @@
GrColorType, GrGpuBuffer* transferBuffer, size_t offset) override {
return true;
}
- bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
- GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+ bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override {
return true;
}
diff --git a/src/gpu/mock/GrMockGpuCommandBuffer.h b/src/gpu/mock/GrMockGpuCommandBuffer.h
index 9e2905e..7532bdc 100644
--- a/src/gpu/mock/GrMockGpuCommandBuffer.h
+++ b/src/gpu/mock/GrMockGpuCommandBuffer.h
@@ -19,8 +19,7 @@
~GrMockGpuTextureCommandBuffer() override {}
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override {}
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override {}
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) override {}
void insertEventMarker(const char*) override {}
@@ -42,8 +41,7 @@
void insertEventMarker(const char*) override {}
void begin() override {}
void end() override {}
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override {}
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override {}
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) override {}
diff --git a/src/gpu/mtl/GrMtlCaps.h b/src/gpu/mtl/GrMtlCaps.h
index 7939dc2..2ee1d88 100644
--- a/src/gpu/mtl/GrMtlCaps.h
+++ b/src/gpu/mtl/GrMtlCaps.h
@@ -46,18 +46,11 @@
return fPreferredStencilFormat;
}
- bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCount, GrSurfaceOrigin dstOrigin,
- GrPixelConfig srcConfig, int srcSampleCount, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCount, GrPixelConfig srcConfig,
+ int srcSampleCount, const SkIRect& srcRect, const SkIPoint& dstPoint,
bool areDstSrcSameObj) const;
- bool canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable,
- GrPixelConfig srcConfig, bool srcIsTextureable) const;
-
- bool canCopyAsDrawThenBlit(GrPixelConfig dstConfig, GrPixelConfig srcConfig,
- bool srcIsTextureable) const;
-
- bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
+ bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
bool* rectsMustMatch, bool* disallowSubrect) const override {
return false;
}
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 04a87ae..7e630d2 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -119,9 +119,7 @@
}
bool GrMtlCaps::canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCount,
- GrSurfaceOrigin dstOrigin,
GrPixelConfig srcConfig, int srcSampleCount,
- GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect, const SkIPoint& dstPoint,
bool areDstSrcSameObj) const {
if (dstConfig != srcConfig) {
@@ -130,9 +128,6 @@
if ((dstSampleCount > 1 || srcSampleCount > 1) && (dstSampleCount != srcSampleCount)) {
return false;
}
- if (dstOrigin != srcOrigin) {
- return false;
- }
if (areDstSrcSameObj) {
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.x(), dstPoint.y(),
srcRect.width(), srcRect.height());
@@ -143,38 +138,8 @@
return true;
}
-bool GrMtlCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable,
- GrPixelConfig srcConfig, bool srcIsTextureable) const {
- // TODO: Make copySurfaceAsDraw handle the swizzle
- if (this->shaderCaps()->configOutputSwizzle(srcConfig) !=
- this->shaderCaps()->configOutputSwizzle(dstConfig)) {
- return false;
- }
-
- if (!dstIsRenderable || !srcIsTextureable) {
- return false;
- }
- return true;
-}
-
-bool GrMtlCaps::canCopyAsDrawThenBlit(GrPixelConfig dstConfig, GrPixelConfig srcConfig,
- bool srcIsTextureable) const {
- // TODO: Make copySurfaceAsDraw handle the swizzle
- if (this->shaderCaps()->configOutputSwizzle(srcConfig) !=
- this->shaderCaps()->configOutputSwizzle(dstConfig)) {
- return false;
- }
- if (!srcIsTextureable) {
- return false;
- }
- return true;
-}
-
bool GrMtlCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
- GrSurfaceOrigin dstOrigin = dst->origin();
- GrSurfaceOrigin srcOrigin = src->origin();
-
int dstSampleCnt = 0;
int srcSampleCnt = 0;
if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
@@ -186,13 +151,8 @@
SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
- return this->canCopyAsBlit(dst->config(), dstSampleCnt, dstOrigin,
- src->config(), srcSampleCnt, srcOrigin,
- srcRect, dstPoint, dst == src) ||
- this->canCopyAsDraw(dst->config(), SkToBool(dst->asRenderTargetProxy()),
- src->config(), SkToBool(src->asTextureProxy())) ||
- this->canCopyAsDrawThenBlit(dst->config(), src->config(),
- SkToBool(src->asTextureProxy()));
+ return this->canCopyAsBlit(dst->config(), dstSampleCnt, src->config(), srcSampleCnt, srcRect,
+ dstPoint, dst == src);
}
void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
diff --git a/src/gpu/mtl/GrMtlCopyManager.h b/src/gpu/mtl/GrMtlCopyManager.h
deleted file mode 100644
index 68d1a22..0000000
--- a/src/gpu/mtl/GrMtlCopyManager.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
-*/
-
-#ifndef GrMtlCopyManager_DEFINED
-#define GrMtlCopyManager_DEFINED
-
-#include "include/gpu/GrTypes.h"
-
-#import <metal/metal.h>
-
-class GrMtlCopyPipelineState;
-class GrMtlGpu;
-class GrSurface;
-struct SkIPoint;
-struct SkIRect;
-
-class GrMtlCopyManager {
-public:
- GrMtlCopyManager(GrMtlGpu* gpu) : fGpu(gpu) {}
-
- bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect);
-
- static bool IsCompatible(const GrMtlCopyPipelineState*, MTLPixelFormat dstPixelFormat);
-
- void destroyResources();
-
-private:
- enum BufferIndex {
- kUniform_BufferIndex,
- kAttribute_BufferIndex,
- };
-
- void createCopyProgramBuffer();
- void createCopyProgramShaders();
- void createCopyProgramVertexDescriptor();
-
- void createCopyProgram();
-
- id<MTLSamplerState> fSamplerState;
- id<MTLBuffer> fVertexAttributeBuffer;
- id<MTLFunction> fVertexFunction;
- id<MTLFunction> fFragmentFunction;
- MTLVertexDescriptor* fVertexDescriptor;
-
- GrMtlGpu* fGpu;
-};
-
-#endif
diff --git a/src/gpu/mtl/GrMtlCopyManager.mm b/src/gpu/mtl/GrMtlCopyManager.mm
deleted file mode 100644
index b79950f..0000000
--- a/src/gpu/mtl/GrMtlCopyManager.mm
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/gpu/mtl/GrMtlCopyManager.h"
-
-#include "include/gpu/GrSurface.h"
-
-#include "src/gpu/mtl/GrMtlBuffer.h"
-#include "src/gpu/mtl/GrMtlCommandBuffer.h"
-#include "src/gpu/mtl/GrMtlCopyPipelineState.h"
-#include "src/gpu/mtl/GrMtlGpu.h"
-#include "src/gpu/mtl/GrMtlResourceProvider.h"
-#include "src/gpu/mtl/GrMtlUtil.h"
-
-#include "include/core/SkPoint.h"
-#include "include/core/SkRect.h"
-#include "src/core/SkTraceEvent.h"
-
-#import <simd/simd.h>
-
-#if !__has_feature(objc_arc)
-#error This file must be compiled with Arc. Use -fobjc-arc flag
-#endif
-
-void GrMtlCopyManager::createCopyProgramBuffer() {
- // Create per vertex attribute data for copy as draw
- static const simd::float2 vdata[4] = {
- {0, 0},
- {0, 1},
- {1, 0},
- {1, 1},
- };
- sk_sp<GrMtlBuffer> mtlBuffer = GrMtlBuffer::Make(fGpu, sizeof(vdata), GrGpuBufferType::kVertex,
- kStatic_GrAccessPattern, vdata);
- fVertexAttributeBuffer = mtlBuffer->mtlBuffer();
-}
-
-void GrMtlCopyManager::createCopyProgramShaders() {
- // Create shaders required by pipeline state
- const GrShaderCaps* shaderCaps = fGpu->caps()->shaderCaps();
- const char* version = shaderCaps->versionDeclString();
- SkString vertShaderText(version);
- vertShaderText.appendf(
- "#extension GL_ARB_separate_shader_objects : enable\n"
- "#extension GL_ARB_shading_language_420pack : enable\n"
- "layout(set = %d"/*kUniform_BufferIndex*/", binding = 0) uniform vertexUniformBuffer {"
- "float4 uPosXform;"
- "float4 uTexCoordXform;"
- "};"
- "layout(location = 0) in float2 inPosition;"
- "layout(location = 1) out float2 vTexCoord;"
-
- "// Copy Program VS\n"
- "void main() {"
- "vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;"
- "sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;"
- "sk_Position.zw = float2(0, 1);"
- "}",
- kUniform_BufferIndex
- );
-
- SkString fragShaderText(version);
- fragShaderText.append(
- "#extension GL_ARB_separate_shader_objects : enable\n"
- "#extension GL_ARB_shading_language_420pack : enable\n"
-
- "layout(set = 1, binding = 0) uniform sampler2D uTexture;"
- "layout(location = 1) in float2 vTexCoord;"
-
- "// Copy Program FS\n"
- "void main() {"
- "sk_FragColor = texture(uTexture, vTexCoord);"
- "}"
- );
-
- SkSL::Program::Settings settings;
- SkSL::Program::Inputs inputs;
- id<MTLLibrary> vertexLibrary = GrCompileMtlShaderLibrary(fGpu, vertShaderText.c_str(),
- SkSL::Program::kVertex_Kind,
- settings, &inputs);
- SkASSERT(inputs.isEmpty());
- SkASSERT(vertexLibrary);
-
- id<MTLLibrary> fragmentLibrary = GrCompileMtlShaderLibrary(fGpu, fragShaderText.c_str(),
- SkSL::Program::kFragment_Kind,
- settings, &inputs);
- SkASSERT(inputs.isEmpty());
- SkASSERT(fragmentLibrary);
-
- id<MTLFunction> vertexFunction = [vertexLibrary newFunctionWithName: @"vertexMain"];
- id<MTLFunction> fragmentFunction = [fragmentLibrary newFunctionWithName: @"fragmentMain"];
- SkASSERT(vertexFunction);
- SkASSERT(fragmentFunction);
-
- fVertexFunction = vertexFunction;
- fFragmentFunction = fragmentFunction;
-}
-
-void GrMtlCopyManager::createCopyProgramVertexDescriptor() {
- // Create vertex descriptor for pipeline state
- // Expected [[stage_in]] (vertex attribute) MSL format for copies:
- //
- // struct Input {
- // float2 inPosition [[attribute(0)]];
- // };
- MTLVertexDescriptor* vertexDescriptor = [[MTLVertexDescriptor alloc] init];
- vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2;
- vertexDescriptor.attributes[0].offset = 0;
- vertexDescriptor.attributes[0].bufferIndex = kAttribute_BufferIndex;
-
- vertexDescriptor.layouts[kAttribute_BufferIndex].stepFunction = MTLVertexStepFunctionPerVertex;
- vertexDescriptor.layouts[kAttribute_BufferIndex].stepRate = 1;
- vertexDescriptor.layouts[kAttribute_BufferIndex].stride = sizeof(simd::float2);
-
- fVertexDescriptor = vertexDescriptor;
-}
-
-void GrMtlCopyManager::createCopyProgram() {
- TRACE_EVENT0("skia", TRACE_FUNC);
-
- MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init];
- fSamplerState = [fGpu->device() newSamplerStateWithDescriptor: samplerDescriptor];
-
- this->createCopyProgramBuffer();
- this->createCopyProgramShaders();
- this->createCopyProgramVertexDescriptor();
-}
-
-bool GrMtlCopyManager::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) {
- SkASSERT(fGpu->mtlCaps().canCopyAsDraw(dst->config(), SkToBool(dst->asRenderTarget()),
- src->config(), SkToBool(src->asTexture())));
-
- id<MTLTexture> dstTex = GrGetMTLTextureFromSurface(dst, false);
- id<MTLTexture> srcTex = GrGetMTLTextureFromSurface(src, false);
- SkASSERT(srcTex != dstTex);
-
- if (fSamplerState == nil) {
- SkASSERT(fVertexAttributeBuffer == nil);
- SkASSERT(fVertexFunction == nil);
- SkASSERT(fFragmentFunction == nil);
- SkASSERT(fVertexDescriptor == nil);
-
- this->createCopyProgram();
- }
-
- if (!(fSamplerState && fVertexAttributeBuffer && fVertexFunction &&
- fFragmentFunction && fVertexDescriptor)) {
- SkASSERT(false);
- return false;
- }
-
- // UPDATE UNIFORM DESCRIPTOR SET
- int w = srcRect.width();
- int h = srcRect.height();
-
- // dst rect edges in NDC (-1 to 1)
- int dw = dstTex.width;
- int dh = dstTex.height;
- float dx0 = 2.f * dstPoint.fX / dw - 1.f;
- float dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
- float dy0 = 2.f * dstPoint.fY / dh - 1.f;
- float dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
- if (kBottomLeft_GrSurfaceOrigin == dstOrigin) {
- dy0 = -dy0;
- dy1 = -dy1;
- }
-
- float sx0 = (float)srcRect.fLeft;
- float sx1 = (float)(srcRect.fLeft + w);
- float sy0 = (float)srcRect.fTop;
- float sy1 = (float)(srcRect.fTop + h);
- int sh = srcTex.height;
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- sy0 = sh - sy0;
- sy1 = sh - sy1;
- }
-
- // src rect edges in normalized texture space (0 to 1).
- int sw = srcTex.width;
- sx0 /= sw;
- sx1 /= sw;
- sy0 /= sh;
- sy1 /= sh;
-
- const simd::float4 vertexUniformBuffer[2] = {
- {dx1 - dx0, dy1 - dy0, dx0, dy0}, // posXform
- {sx1 - sx0, sy1 - sy0, sx0, sy0}, // texCoordXform
- };
-
- MTLRenderPassDescriptor* renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor];
- renderPassDesc.colorAttachments[0].texture = dstTex;
- renderPassDesc.colorAttachments[0].slice = 0;
- renderPassDesc.colorAttachments[0].level = 0;
- renderPassDesc.colorAttachments[0].loadAction = canDiscardOutsideDstRect ? MTLLoadActionDontCare
- : MTLLoadActionLoad;
- renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
-
- id<MTLRenderCommandEncoder> renderCmdEncoder =
- fGpu->commandBuffer()->getRenderCommandEncoder(renderPassDesc, nullptr);
- GrMtlCopyPipelineState* copyPipelineState =
- fGpu->resourceProvider().findOrCreateCopyPipelineState(dstTex.pixelFormat,
- fVertexFunction,
- fFragmentFunction,
- fVertexDescriptor);
- [renderCmdEncoder setRenderPipelineState: copyPipelineState->mtlCopyPipelineState()];
- [renderCmdEncoder setVertexBuffer: fVertexAttributeBuffer
- offset: 0
- atIndex: kAttribute_BufferIndex];
- [renderCmdEncoder setVertexBytes: vertexUniformBuffer
- length: sizeof(vertexUniformBuffer)
- atIndex: kUniform_BufferIndex];
- [renderCmdEncoder setFragmentTexture: srcTex
- atIndex: 0];
- [renderCmdEncoder setFragmentSamplerState: fSamplerState
- atIndex: 0];
- [renderCmdEncoder drawPrimitives: MTLPrimitiveTypeTriangleStrip
- vertexStart: 0
- vertexCount: 4];
- return true;
-}
-
-bool GrMtlCopyManager::IsCompatible(const GrMtlCopyPipelineState* pipelineState,
- MTLPixelFormat dstPixelFormat) {
- return pipelineState->fPixelFormat == dstPixelFormat;
-}
-
-void GrMtlCopyManager::destroyResources() {
- fSamplerState = nil;
- fVertexAttributeBuffer = nil;
- fVertexFunction = nil;
- fFragmentFunction = nil;
- fVertexDescriptor = nil;
-}
diff --git a/src/gpu/mtl/GrMtlCopyPipelineState.h b/src/gpu/mtl/GrMtlCopyPipelineState.h
deleted file mode 100644
index ce4cbb2..0000000
--- a/src/gpu/mtl/GrMtlCopyPipelineState.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrMtlCopyPipelineState_DEFINED
-#define GrMtlCopyPipelineState_DEFINED
-
-#import <metal/metal.h>
-
-class GrMtlGpu;
-
-class GrMtlCopyPipelineState {
-public:
- static GrMtlCopyPipelineState* CreateCopyPipelineState(GrMtlGpu* gpu,
- MTLPixelFormat dstPixelFormat,
- id<MTLFunction> vertexFunction,
- id<MTLFunction> fragmentFunction,
- MTLVertexDescriptor* vertexDescriptor);
-
- id<MTLRenderPipelineState> mtlCopyPipelineState() { return fPipelineState; }
-
-private:
- GrMtlCopyPipelineState(id<MTLRenderPipelineState> pipelineState,
- MTLPixelFormat pixelFormat)
- : fPipelineState(pipelineState)
- , fPixelFormat(pixelFormat) {}
-
- id<MTLRenderPipelineState> fPipelineState;
- MTLPixelFormat fPixelFormat;
-
- friend class GrMtlCopyManager;
-};
-
-#endif
diff --git a/src/gpu/mtl/GrMtlCopyPipelineState.mm b/src/gpu/mtl/GrMtlCopyPipelineState.mm
deleted file mode 100644
index 43db99d..0000000
--- a/src/gpu/mtl/GrMtlCopyPipelineState.mm
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/gpu/mtl/GrMtlCopyPipelineState.h"
-#include "src/gpu/mtl/GrMtlGpu.h"
-
-#if !__has_feature(objc_arc)
-#error This file must be compiled with Arc. Use -fobjc-arc flag
-#endif
-
-GrMtlCopyPipelineState* GrMtlCopyPipelineState::CreateCopyPipelineState(
- GrMtlGpu* gpu,
- MTLPixelFormat dstPixelFormat,
- id<MTLFunction> vertexFunction,
- id<MTLFunction> fragmentFunction,
- MTLVertexDescriptor* vertexDescriptor) {
-
- // Create pipeline state for copy as draw
- MTLRenderPipelineDescriptor* pipelineDescriptor = [MTLRenderPipelineDescriptor new];
- pipelineDescriptor.vertexFunction = vertexFunction;
- pipelineDescriptor.fragmentFunction = fragmentFunction;
- pipelineDescriptor.vertexDescriptor = vertexDescriptor;
- pipelineDescriptor.colorAttachments[0].pixelFormat = dstPixelFormat;
-
- NSError* error = nil;
- id<MTLRenderPipelineState> pipelineState =
- [gpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
- error: &error];
- if (error) {
- SkDebugf("Error creating pipeline: %s\n",
- [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
- return nil;
- }
-
- SkASSERT(pipelineState);
- return new GrMtlCopyPipelineState(pipelineState, dstPixelFormat);
-}
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 7288daf..32c22fc 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -14,7 +14,6 @@
#include "src/gpu/GrSemaphore.h"
#include "src/gpu/mtl/GrMtlCaps.h"
-#include "src/gpu/mtl/GrMtlCopyManager.h"
#include "src/gpu/mtl/GrMtlResourceProvider.h"
#include "src/gpu/mtl/GrMtlStencilAttachment.h"
@@ -72,22 +71,11 @@
void testingOnly_flushGpuAndSync() override;
#endif
- bool copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint);
+ bool copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint);
- // This function is needed when we want to copy between two surfaces with different origins and
- // the destination surface is not a render target. We will first draw to a temporary render
- // target to adjust for the different origins and then blit from there to the destination.
- bool copySurfaceAsDrawThenBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint);
-
- bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) override;
+ bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override;
GrGpuRTCommandBuffer* getCommandBuffer(
GrRenderTarget*, GrSurfaceOrigin, const SkRect& bounds,
@@ -222,7 +210,6 @@
std::unique_ptr<SkSL::Compiler> fCompiler;
- GrMtlCopyManager fCopyManager;
GrMtlResourceProvider fResourceProvider;
bool fDisconnected;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index a215b0d..6794704 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -99,7 +99,6 @@
, fQueue(queue)
, fCmdBuffer(nullptr)
, fCompiler(new SkSL::Compiler())
- , fCopyManager(this)
, fResourceProvider(this)
, fDisconnected(false) {
fMtlCaps.reset(new GrMtlCaps(options, fDevice, featureSet));
@@ -121,8 +120,6 @@
delete fCmdBuffer;
fCmdBuffer = nullptr;
- // We don't need to distinguish between abandon and destroy for these subsystems
- fCopyManager.destroyResources();
fResourceProvider.destroyResources();
fQueue = nil;
@@ -135,8 +132,6 @@
void GrMtlGpu::destroyResources() {
// Will implicitly delete the command buffer
this->submitCommandBuffer(SyncQueue::kForce_SyncQueue);
-
- fCopyManager.destroyResources();
fResourceProvider.destroyResources();
fQueue = nil;
@@ -864,126 +859,33 @@
return 0;
}
-bool GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
+bool GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint) {
#ifdef SK_DEBUG
int dstSampleCnt = get_surface_sample_cnt(dst);
int srcSampleCnt = get_surface_sample_cnt(src);
- SkASSERT(this->mtlCaps().canCopyAsBlit(dst->config(), dstSampleCnt, dstOrigin,
- src->config(), srcSampleCnt, srcOrigin,
+ SkASSERT(this->mtlCaps().canCopyAsBlit(dst->config(), dstSampleCnt, src->config(), srcSampleCnt,
srcRect, dstPoint, dst == src));
#endif
id<MTLTexture> dstTex = GrGetMTLTextureFromSurface(dst, false);
id<MTLTexture> srcTex = GrGetMTLTextureFromSurface(src, false);
- // Flip rect if necessary
- SkIRect srcMtlRect;
- srcMtlRect.fLeft = srcRect.fLeft;
- srcMtlRect.fRight = srcRect.fRight;
- SkIRect dstRect;
- dstRect.fLeft = dstPoint.fX;
- dstRect.fRight = dstPoint.fX + srcRect.width();
-
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- srcMtlRect.fTop = srcTex.height - srcRect.fBottom;
- srcMtlRect.fBottom = srcTex.height - srcRect.fTop;
- } else {
- srcMtlRect.fTop = srcRect.fTop;
- srcMtlRect.fBottom = srcRect.fBottom;
- }
-
- if (kBottomLeft_GrSurfaceOrigin == dstOrigin) {
- dstRect.fTop = dstTex.height - dstPoint.fY - srcMtlRect.height();
- } else {
- dstRect.fTop = dstPoint.fY;
- }
- dstRect.fBottom = dstRect.fTop + srcMtlRect.height();
-
id<MTLBlitCommandEncoder> blitCmdEncoder = this->commandBuffer()->getBlitCommandEncoder();
[blitCmdEncoder copyFromTexture: srcTex
sourceSlice: 0
sourceLevel: 0
- sourceOrigin: MTLOriginMake(srcMtlRect.x(), srcMtlRect.y(), 0)
- sourceSize: MTLSizeMake(srcMtlRect.width(), srcMtlRect.height(), 1)
+ sourceOrigin: MTLOriginMake(srcRect.x(), srcRect.y(), 0)
+ sourceSize: MTLSizeMake(srcRect.width(), srcRect.height(), 1)
toTexture: dstTex
destinationSlice: 0
destinationLevel: 0
- destinationOrigin: MTLOriginMake(dstRect.x(), dstRect.y(), 0)];
+ destinationOrigin: MTLOriginMake(dstPoint.fX, dstPoint.fY, 0)];
return true;
}
-bool GrMtlGpu::copySurfaceAsDrawThenBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
-#ifdef SK_DEBUG
- int dstSampleCnt = get_surface_sample_cnt(dst);
- int srcSampleCnt = get_surface_sample_cnt(src);
- SkASSERT(dstSampleCnt == 0); // dst shouldn't be a render target
- SkASSERT(!this->mtlCaps().canCopyAsBlit(dst->config(), dstSampleCnt, dstOrigin,
- src->config(), srcSampleCnt, srcOrigin,
- srcRect, dstPoint, dst == src));
- SkASSERT(!this->mtlCaps().canCopyAsDraw(dst->config(), SkToBool(dst->asRenderTarget()),
- src->config(), SkToBool(src->asTexture())));
- SkASSERT(this->mtlCaps().canCopyAsDrawThenBlit(dst->config(),src->config(),
- SkToBool(src->asTexture())));
-#endif
- GrSurfaceDesc surfDesc;
- surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
- surfDesc.fWidth = srcRect.width();
- surfDesc.fHeight = srcRect.height();
- surfDesc.fConfig = dst->config();
- surfDesc.fSampleCnt = 1;
-
- id<MTLTexture> dstTex = GrGetMTLTextureFromSurface(dst, false);
- MTLTextureDescriptor* textureDesc = GrGetMTLTextureDescriptor(dstTex);
- textureDesc.width = srcRect.width();
- textureDesc.height = srcRect.height();
- textureDesc.mipmapLevelCount = 1;
- textureDesc.usage |= MTLTextureUsageRenderTarget;
-
- sk_sp<GrMtlTexture> transferTexture =
- GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(this,
- SkBudgeted::kYes,
- surfDesc,
- textureDesc,
- GrMipMapsStatus::kNotAllocated);
-
- GrSurfaceOrigin transferOrigin = dstOrigin;
- SkASSERT(this->mtlCaps().canCopyAsDraw(transferTexture->config(),
- SkToBool(transferTexture->asRenderTarget()),
- src->config(),
- SkToBool(src->asTexture())));
- // TODO: Eventually we will need to handle resolves either in this function or make a separate
- // copySurfaceAsResolveThenBlit().
- if (!this->copySurface(transferTexture.get(), transferOrigin,
- src, srcOrigin,
- srcRect, SkIPoint::Make(0, 0))) {
- return false;
- }
-
- SkIRect transferRect = SkIRect::MakeXYWH(0, 0, srcRect.width(), srcRect.height());
- SkASSERT(this->mtlCaps().canCopyAsBlit(dst->config(),
- get_surface_sample_cnt(dst),
- dstOrigin,
- transferTexture->config(),
- get_surface_sample_cnt(transferTexture.get()),
- transferOrigin,
- transferRect, dstPoint, false));
- if (!this->copySurface(dst, dstOrigin,
- transferTexture.get(), transferOrigin,
- transferRect, dstPoint)) {
- return false;
- }
- return true;
-}
-
-bool GrMtlGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) {
+bool GrMtlGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) {
GrPixelConfig dstConfig = dst->config();
GrPixelConfig srcConfig = src->config();
@@ -997,23 +899,15 @@
}
bool success = false;
- if (this->mtlCaps().canCopyAsDraw(dst->config(), SkToBool(dst->asRenderTarget()),
- src->config(), SkToBool(src->asTexture()))) {
- success = fCopyManager.copySurfaceAsDraw(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint,
- canDiscardOutsideDstRect);
- } else if (this->mtlCaps().canCopyAsBlit(dstConfig, dstSampleCnt, dstOrigin,
- srcConfig, srcSampleCnt, srcOrigin,
- srcRect, dstPoint, dst == src)) {
- success = this->copySurfaceAsBlit(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
- } else if (this->mtlCaps().canCopyAsDrawThenBlit(dst->config(), src->config(),
- SkToBool(src->asTexture()))) {
- success = this->copySurfaceAsDrawThenBlit(dst, dstOrigin, src, srcOrigin,
- srcRect, dstPoint);
+ if (this->mtlCaps().canCopyAsBlit(dstConfig, dstSampleCnt, srcConfig, srcSampleCnt, srcRect,
+ dstPoint, dst == src)) {
+ success = this->copySurfaceAsBlit(dst, src, srcRect, dstPoint);
}
if (success) {
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.x(), dstPoint.y(),
srcRect.width(), srcRect.height());
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
+ // The rect is already in device space so we pass in kTopLeft so no flip is done.
+ this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
}
return success;
}
diff --git a/src/gpu/mtl/GrMtlGpuCommandBuffer.h b/src/gpu/mtl/GrMtlGpuCommandBuffer.h
index f7a0eb9..062b228 100644
--- a/src/gpu/mtl/GrMtlGpuCommandBuffer.h
+++ b/src/gpu/mtl/GrMtlGpuCommandBuffer.h
@@ -29,9 +29,8 @@
~GrMtlGpuTextureCommandBuffer() override {}
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override {
- fGpu->copySurface(fTexture, fOrigin, src, srcOrigin, srcRect, dstPoint);
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override {
+ fGpu->copySurface(fTexture, src, srcRect, dstPoint);
}
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) override {
@@ -68,8 +67,7 @@
}
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) override;
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override;
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
void submit();
diff --git a/src/gpu/mtl/GrMtlGpuCommandBuffer.mm b/src/gpu/mtl/GrMtlGpuCommandBuffer.mm
index 7354fbe..8dc4c70 100644
--- a/src/gpu/mtl/GrMtlGpuCommandBuffer.mm
+++ b/src/gpu/mtl/GrMtlGpuCommandBuffer.mm
@@ -92,12 +92,12 @@
fGpu->submitIndirectCommandBuffer(fRenderTarget, fOrigin, &iBounds);
}
-void GrMtlGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
+void GrMtlGpuRTCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
+const SkIPoint& dstPoint) {
// We cannot have an active encoder when we call copy since it requires its own
// command encoder.
SkASSERT(nil == fActiveRenderCmdEncoder);
- fGpu->copySurface(fRenderTarget, fOrigin, src, srcOrigin, srcRect, dstPoint);
+ fGpu->copySurface(fRenderTarget, src, srcRect, dstPoint);
}
void GrMtlGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
diff --git a/src/gpu/mtl/GrMtlResourceProvider.h b/src/gpu/mtl/GrMtlResourceProvider.h
index ed20e59..cf19c89 100644
--- a/src/gpu/mtl/GrMtlResourceProvider.h
+++ b/src/gpu/mtl/GrMtlResourceProvider.h
@@ -10,7 +10,6 @@
#include "include/private/SkTArray.h"
#include "src/core/SkLRUCache.h"
-#include "src/gpu/mtl/GrMtlCopyPipelineState.h"
#include "src/gpu/mtl/GrMtlDepthStencil.h"
#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
#include "src/gpu/mtl/GrMtlSampler.h"
@@ -23,11 +22,6 @@
public:
GrMtlResourceProvider(GrMtlGpu* gpu);
- GrMtlCopyPipelineState* findOrCreateCopyPipelineState(MTLPixelFormat dstPixelFormat,
- id<MTLFunction> vertexFunction,
- id<MTLFunction> fragmentFunction,
- MTLVertexDescriptor* vertexDescriptor);
-
GrMtlPipelineState* findOrCreateCompatiblePipelineState(
GrRenderTarget*, GrSurfaceOrigin,
const GrPipeline&,
@@ -89,8 +83,6 @@
#endif
};
- SkTArray<std::unique_ptr<GrMtlCopyPipelineState>> fCopyPipelineStateCache;
-
GrMtlGpu* fGpu;
// Cache of GrMtlPipelineStates
diff --git a/src/gpu/mtl/GrMtlResourceProvider.mm b/src/gpu/mtl/GrMtlResourceProvider.mm
index e3a63c7..f447984 100644
--- a/src/gpu/mtl/GrMtlResourceProvider.mm
+++ b/src/gpu/mtl/GrMtlResourceProvider.mm
@@ -8,7 +8,6 @@
#include "src/gpu/mtl/GrMtlResourceProvider.h"
#include "src/gpu/mtl/GrMtlCommandBuffer.h"
-#include "src/gpu/mtl/GrMtlCopyManager.h"
#include "src/gpu/mtl/GrMtlGpu.h"
#include "src/gpu/mtl/GrMtlPipelineState.h"
#include "src/gpu/mtl/GrMtlUtil.h"
@@ -25,23 +24,6 @@
fPipelineStateCache.reset(new PipelineStateCache(gpu));
}
-GrMtlCopyPipelineState* GrMtlResourceProvider::findOrCreateCopyPipelineState(
- MTLPixelFormat dstPixelFormat,
- id<MTLFunction> vertexFunction,
- id<MTLFunction> fragmentFunction,
- MTLVertexDescriptor* vertexDescriptor) {
-
- for (const auto& copyPipelineState: fCopyPipelineStateCache) {
- if (GrMtlCopyManager::IsCompatible(copyPipelineState.get(), dstPixelFormat)) {
- return copyPipelineState.get();
- }
- }
-
- fCopyPipelineStateCache.emplace_back(GrMtlCopyPipelineState::CreateCopyPipelineState(
- fGpu, dstPixelFormat, vertexFunction, fragmentFunction, vertexDescriptor));
- return fCopyPipelineStateCache.back().get();
-}
-
GrMtlPipelineState* GrMtlResourceProvider::findOrCreateCompatiblePipelineState(
GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
const GrPipeline& pipeline, const GrPrimitiveProcessor& proc,
diff --git a/src/gpu/ops/GrCopySurfaceOp.cpp b/src/gpu/ops/GrCopySurfaceOp.cpp
index df64f3a..0dfcc29 100644
--- a/src/gpu/ops/GrCopySurfaceOp.cpp
+++ b/src/gpu/ops/GrCopySurfaceOp.cpp
@@ -11,57 +11,7 @@
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrRecordingContextPriv.h"
-
-// returns true if the read/written rect intersects the src/dst and false if not.
-static bool clip_src_rect_and_dst_point(const GrSurfaceProxy* dst,
- const GrSurfaceProxy* src,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint,
- SkIRect* clippedSrcRect,
- SkIPoint* clippedDstPoint) {
- *clippedSrcRect = srcRect;
- *clippedDstPoint = dstPoint;
-
- // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
- if (clippedSrcRect->fLeft < 0) {
- clippedDstPoint->fX -= clippedSrcRect->fLeft;
- clippedSrcRect->fLeft = 0;
- }
- if (clippedDstPoint->fX < 0) {
- clippedSrcRect->fLeft -= clippedDstPoint->fX;
- clippedDstPoint->fX = 0;
- }
-
- // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
- if (clippedSrcRect->fTop < 0) {
- clippedDstPoint->fY -= clippedSrcRect->fTop;
- clippedSrcRect->fTop = 0;
- }
- if (clippedDstPoint->fY < 0) {
- clippedSrcRect->fTop -= clippedDstPoint->fY;
- clippedDstPoint->fY = 0;
- }
-
- // clip the right edge to the src and dst bounds.
- if (clippedSrcRect->fRight > src->width()) {
- clippedSrcRect->fRight = src->width();
- }
- if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) {
- clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX;
- }
-
- // clip the bottom edge to the src and dst bounds.
- if (clippedSrcRect->fBottom > src->height()) {
- clippedSrcRect->fBottom = src->height();
- }
- if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) {
- clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY;
- }
-
- // The above clipping steps may have inverted the rect if it didn't intersect either the src or
- // dst bounds.
- return !clippedSrcRect->isEmpty();
-}
+#include "src/gpu/geometry/GrRect.h"
std::unique_ptr<GrOp> GrCopySurfaceOp::Make(GrRecordingContext* context,
GrSurfaceProxy* dstProxy,
@@ -73,22 +23,54 @@
SkIRect clippedSrcRect;
SkIPoint clippedDstPoint;
// If the rect is outside the srcProxy or dstProxy then we've already succeeded.
- if (!clip_src_rect_and_dst_point(dstProxy, srcProxy, srcRect, dstPoint,
- &clippedSrcRect, &clippedDstPoint)) {
+ if (!GrClipSrcRectAndDstPoint(dstProxy->isize(), srcProxy->isize(), srcRect, dstPoint,
+ &clippedSrcRect, &clippedDstPoint)) {
return nullptr;
}
if (GrPixelConfigIsCompressed(dstProxy->config())) {
return nullptr;
}
+ SkASSERT(dstProxy->origin() == srcProxy->origin());
+ SkIRect adjSrcRect;
+ adjSrcRect.fLeft = clippedSrcRect.fLeft;
+ adjSrcRect.fRight = clippedSrcRect.fRight;
+ SkIPoint adjDstPoint;
+ adjDstPoint.fX = clippedDstPoint.fX;
+
+ // If it is bottom left origin we must flip the rects.
+ SkASSERT(dstProxy->origin() == srcProxy->origin());
+ if (kBottomLeft_GrSurfaceOrigin == srcProxy->origin()) {
+ adjSrcRect.fTop = srcProxy->height() - clippedSrcRect.fBottom;
+ adjSrcRect.fBottom = srcProxy->height() - clippedSrcRect.fTop;
+ adjDstPoint.fY = dstProxy->height() - clippedDstPoint.fY - clippedSrcRect.height();
+ } else {
+ adjSrcRect.fTop = clippedSrcRect.fTop;
+ adjSrcRect.fBottom = clippedSrcRect.fBottom;
+ adjDstPoint.fY = clippedDstPoint.fY;
+ }
+
GrOpMemoryPool* pool = context->priv().opMemoryPool();
- return pool->allocate<GrCopySurfaceOp>(srcProxy, clippedSrcRect, clippedDstPoint);
+ return pool->allocate<GrCopySurfaceOp>(srcProxy, dstProxy, adjSrcRect, adjDstPoint);
}
void GrCopySurfaceOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
SkASSERT(fSrc.get()->isInstantiated());
- state->commandBuffer()->copy(fSrc.get()->peekSurface(), fSrc.get()->origin(), fSrcRect,
- fDstPoint);
+ // If we are using approx surfaces we may need to adjust our srcRect or dstPoint if the origin
+ // is bottom left.
+ GrSurfaceProxy* src = fSrc.get();
+ if (src->origin() == kBottomLeft_GrSurfaceOrigin) {
+ GrSurfaceProxy* dst = fDst.get();
+ SkASSERT(dst->isInstantiated());
+ if (src->height() != src->peekSurface()->height()) {
+ fSrcRect.offset(0, src->peekSurface()->height() - src->height());
+ }
+ if (dst->height() != dst->peekSurface()->height()) {
+ fDstPoint.fY = fDstPoint.fY + (dst->peekSurface()->height() - dst->height());
+ }
+ }
+
+ state->commandBuffer()->copy(fSrc.get()->peekSurface(), fSrcRect, fDstPoint);
}
diff --git a/src/gpu/ops/GrCopySurfaceOp.h b/src/gpu/ops/GrCopySurfaceOp.h
index 794a7f5..58e196b 100644
--- a/src/gpu/ops/GrCopySurfaceOp.h
+++ b/src/gpu/ops/GrCopySurfaceOp.h
@@ -45,9 +45,11 @@
private:
friend class GrOpMemoryPool; // for ctor
- GrCopySurfaceOp(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint)
+ GrCopySurfaceOp(GrSurfaceProxy* src, GrSurfaceProxy* dst, const SkIRect& srcRect,
+ const SkIPoint& dstPoint)
: INHERITED(ClassID())
, fSrc(src)
+ , fDst(dst)
, fSrcRect(srcRect)
, fDstPoint(dstPoint) {
SkRect bounds =
@@ -61,6 +63,7 @@
void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fSrc;
+ GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fDst;
SkIRect fSrcRect;
SkIPoint fDstPoint;
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 4fa5dc5..976df7f 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -54,8 +54,7 @@
}
bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
- GrSurfaceOrigin* origin, bool* rectsMustMatch,
- bool* disallowSubrect) const {
+ bool* rectsMustMatch, bool* disallowSubrect) const {
// Vk doesn't use rectsMustMatch or disallowSubrect. Always return false.
*rectsMustMatch = false;
*disallowSubrect = false;
@@ -63,7 +62,6 @@
// We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa).
// For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a
// render target as well.
- *origin = src->origin();
desc->fConfig = src->config();
if (src->numColorSamples() > 1 || src->asTextureProxy()) {
desc->fFlags = kRenderTarget_GrSurfaceFlag;
@@ -115,9 +113,8 @@
return 0;
}
-bool GrVkCaps::canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin,
- bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSampleCnt,
- GrSurfaceOrigin srcOrigin, bool srcHasYcbcr) const {
+bool GrVkCaps::canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, bool dstHasYcbcr,
+ GrPixelConfig srcConfig, int srcSampleCnt, bool srcHasYcbcr) const {
if ((dstSampleCnt > 1 || srcSampleCnt > 1) && dstSampleCnt != srcSampleCnt) {
return false;
}
@@ -128,8 +125,7 @@
// We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
// as image usage flags.
- if (srcOrigin != dstOrigin ||
- get_compatible_format_class(srcConfig) != get_compatible_format_class(dstConfig)) {
+ if (get_compatible_format_class(srcConfig) != get_compatible_format_class(dstConfig)) {
return false;
}
@@ -174,10 +170,8 @@
return true;
}
-bool GrVkCaps::canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt,
- GrSurfaceOrigin dstOrigin, bool dstHasYcbcr,
- GrPixelConfig srcConfig, int srcSampleCnt,
- GrSurfaceOrigin srcOrigin, bool srcHasYcbcr) const {
+bool GrVkCaps::canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt, bool dstHasYcbcr,
+ GrPixelConfig srcConfig, int srcSampleCnt, bool srcHasYcbcr) const {
// The src surface must be multisampled.
if (srcSampleCnt <= 1) {
return false;
@@ -193,11 +187,6 @@
return false;
}
- // Surfaces must have the same origin.
- if (srcOrigin != dstOrigin) {
- return false;
- }
-
if (dstHasYcbcr || srcHasYcbcr) {
return false;
}
@@ -205,32 +194,8 @@
return true;
}
-bool GrVkCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable, bool dstHasYcbcr,
- GrPixelConfig srcConfig, bool srcIsTextureable,
- bool srcHasYcbcr) const {
- // TODO: Make copySurfaceAsDraw handle the swizzle
- if (this->shaderCaps()->configOutputSwizzle(srcConfig) !=
- this->shaderCaps()->configOutputSwizzle(dstConfig)) {
- return false;
- }
-
- // Make sure the dst is a render target and the src is a texture.
- if (!dstIsRenderable || !srcIsTextureable) {
- return false;
- }
-
- if (dstHasYcbcr) {
- return false;
- }
-
- return true;
-}
-
bool GrVkCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
- GrSurfaceOrigin dstOrigin = dst->origin();
- GrSurfaceOrigin srcOrigin = src->origin();
-
GrPixelConfig dstConfig = dst->config();
GrPixelConfig srcConfig = src->config();
@@ -278,14 +243,12 @@
}
}
- return this->canCopyImage(dstConfig, dstSampleCnt, dstOrigin, dstHasYcbcr,
- srcConfig, srcSampleCnt, srcOrigin, srcHasYcbcr) ||
+ return this->canCopyImage(dstConfig, dstSampleCnt, dstHasYcbcr,
+ srcConfig, srcSampleCnt, srcHasYcbcr) ||
this->canCopyAsBlit(dstConfig, dstSampleCnt, dstIsLinear, dstHasYcbcr,
srcConfig, srcSampleCnt, srcIsLinear, srcHasYcbcr) ||
- this->canCopyAsResolve(dstConfig, dstSampleCnt, dstOrigin, dstHasYcbcr,
- srcConfig, srcSampleCnt, srcOrigin, srcHasYcbcr) ||
- this->canCopyAsDraw(dstConfig, dstSampleCnt > 0, dstHasYcbcr,
- srcConfig, SkToBool(src->asTextureProxy()), srcHasYcbcr);
+ this->canCopyAsResolve(dstConfig, dstSampleCnt, dstHasYcbcr,
+ srcConfig, srcSampleCnt, srcHasYcbcr);
}
template<typename T> T* get_extension_feature_struct(const VkPhysicalDeviceFeatures2& features,
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 9fa324c..d795bb3 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -139,22 +139,17 @@
* the surface is not a render target, otherwise it is the number of samples in the render
* target.
*/
- bool canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin,
- bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSamplecnt,
- GrSurfaceOrigin srcOrigin, bool srcHasYcbcr) const;
+ bool canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, bool dstHasYcbcr,
+ GrPixelConfig srcConfig, int srcSamplecnt, bool srcHasYcbcr) const;
bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt, bool dstIsLinear,
bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSampleCnt,
bool srcIsLinear, bool srcHasYcbcr) const;
- bool canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin,
- bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSamplecnt,
- GrSurfaceOrigin srcOrigin, bool srcHasYcbcr) const;
+ bool canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt, bool dstHasYcbcr,
+ GrPixelConfig srcConfig, int srcSamplecnt, bool srcHasYcbcr) const;
- bool canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable, bool dstHasYcbcr,
- GrPixelConfig srcConfig, bool srcIsTextureable, bool srcHasYcbcr) const;
-
- bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
+ bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
bool* rectsMustMatch, bool* disallowSubrect) const override;
GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&,
diff --git a/src/gpu/vk/GrVkCopyManager.cpp b/src/gpu/vk/GrVkCopyManager.cpp
deleted file mode 100644
index ce9a3f9..0000000
--- a/src/gpu/vk/GrVkCopyManager.cpp
+++ /dev/null
@@ -1,460 +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 "src/gpu/vk/GrVkCopyManager.h"
-
-#include "include/core/SkPoint.h"
-#include "include/core/SkRect.h"
-#include "include/gpu/GrSamplerState.h"
-#include "include/gpu/GrSurface.h"
-#include "src/core/SkTraceEvent.h"
-#include "src/gpu/GrRenderTargetPriv.h"
-#include "src/gpu/GrShaderCaps.h"
-#include "src/gpu/GrTexturePriv.h"
-#include "src/gpu/vk/GrVkCommandBuffer.h"
-#include "src/gpu/vk/GrVkCommandPool.h"
-#include "src/gpu/vk/GrVkCopyPipeline.h"
-#include "src/gpu/vk/GrVkDescriptorSet.h"
-#include "src/gpu/vk/GrVkGpu.h"
-#include "src/gpu/vk/GrVkImageView.h"
-#include "src/gpu/vk/GrVkPipelineLayout.h"
-#include "src/gpu/vk/GrVkRenderTarget.h"
-#include "src/gpu/vk/GrVkResourceProvider.h"
-#include "src/gpu/vk/GrVkSampler.h"
-#include "src/gpu/vk/GrVkTexture.h"
-#include "src/gpu/vk/GrVkUniformBuffer.h"
-#include "src/gpu/vk/GrVkVertexBuffer.h"
-
-GrVkCopyManager::GrVkCopyManager()
- : fVertShaderModule(VK_NULL_HANDLE)
- , fFragShaderModule(VK_NULL_HANDLE)
- , fPipelineLayout(nullptr) {}
-
-GrVkCopyManager::~GrVkCopyManager() {}
-
-bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) {
- TRACE_EVENT0("skia", TRACE_FUNC);
-
- const GrShaderCaps* shaderCaps = gpu->caps()->shaderCaps();
- const char* version = shaderCaps->versionDeclString();
- SkSL::String vertShaderText(version);
- vertShaderText.append(
- "#extension GL_ARB_separate_shader_objects : enable\n"
- "#extension GL_ARB_shading_language_420pack : enable\n"
-
- "layout(set = 0, binding = 0) uniform vertexUniformBuffer {"
- "half4 uPosXform;"
- "half4 uTexCoordXform;"
- "};"
- "layout(location = 0) in float2 inPosition;"
- "layout(location = 1) out half2 vTexCoord;"
-
- "// Copy Program VS\n"
- "void main() {"
- "vTexCoord = half2(inPosition * uTexCoordXform.xy + uTexCoordXform.zw);"
- "sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;"
- "sk_Position.zw = half2(0, 1);"
- "}"
- );
-
- SkSL::String fragShaderText(version);
- fragShaderText.append(
- "#extension GL_ARB_separate_shader_objects : enable\n"
- "#extension GL_ARB_shading_language_420pack : enable\n"
-
- "layout(set = 1, binding = 0) uniform sampler2D uTextureSampler;"
- "layout(location = 1) in half2 vTexCoord;"
-
- "// Copy Program FS\n"
- "void main() {"
- "sk_FragColor = texture(uTextureSampler, vTexCoord);"
- "}"
- );
-
- SkSL::Program::Settings settings;
- SkSL::String spirv;
- SkSL::Program::Inputs inputs;
- if (!GrCompileVkShaderModule(gpu, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT,
- &fVertShaderModule, &fShaderStageInfo[0], settings, &spirv,
- &inputs)) {
- this->destroyResources(gpu);
- return false;
- }
- SkASSERT(inputs.isEmpty());
-
- if (!GrCompileVkShaderModule(gpu, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
- &fFragShaderModule, &fShaderStageInfo[1], settings, &spirv,
- &inputs)) {
- this->destroyResources(gpu);
- return false;
- }
- SkASSERT(inputs.isEmpty());
-
- VkDescriptorSetLayout dsLayout[2];
-
- GrVkResourceProvider& resourceProvider = gpu->resourceProvider();
-
- dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
-
- uint32_t samplerVisibility = kFragment_GrShaderFlag;
- SkTArray<uint32_t> visibilityArray(&samplerVisibility, 1);
-
- resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- visibilityArray, &fSamplerDSHandle);
- dsLayout[GrVkUniformHandler::kSamplerDescSet] =
- resourceProvider.getSamplerDSLayout(fSamplerDSHandle);
-
- // Create the VkPipelineLayout
- VkPipelineLayoutCreateInfo layoutCreateInfo;
- memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
- layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
- layoutCreateInfo.pNext = 0;
- layoutCreateInfo.flags = 0;
- layoutCreateInfo.setLayoutCount = 2;
- layoutCreateInfo.pSetLayouts = dsLayout;
- layoutCreateInfo.pushConstantRangeCount = 0;
- layoutCreateInfo.pPushConstantRanges = nullptr;
-
- VkPipelineLayout pipelineLayout;
- VkResult err = GR_VK_CALL(gpu->vkInterface(), CreatePipelineLayout(gpu->device(),
- &layoutCreateInfo,
- nullptr,
- &pipelineLayout));
- if (err) {
- this->destroyResources(gpu);
- return false;
- }
-
- fPipelineLayout = new GrVkPipelineLayout(pipelineLayout);
-
- static const float vdata[] = {
- 0, 0,
- 0, 1,
- 1, 0,
- 1, 1
- };
- fVertexBuffer = GrVkVertexBuffer::Make(gpu, sizeof(vdata), false);
- SkASSERT(fVertexBuffer.get());
- fVertexBuffer->updateData(vdata, sizeof(vdata));
-
- // We use 2 float4's for uniforms
- fUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, 8 * sizeof(float)));
- SkASSERT(fUniformBuffer.get());
-
- return true;
-}
-
-bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
- GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) {
- // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
- // swizzle.
- if (gpu->caps()->shaderCaps()->configOutputSwizzle(src->config()) !=
- gpu->caps()->shaderCaps()->configOutputSwizzle(dst->config())) {
- return false;
- }
-
- GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(dst->asRenderTarget());
- if (!rt) {
- return false;
- }
-
- GrVkTexture* srcTex = static_cast<GrVkTexture*>(src->asTexture());
- if (!srcTex) {
- return false;
- }
-
- if (VK_NULL_HANDLE == fVertShaderModule) {
- SkASSERT(VK_NULL_HANDLE == fFragShaderModule &&
- nullptr == fPipelineLayout &&
- nullptr == fVertexBuffer.get() &&
- nullptr == fUniformBuffer.get());
- if (!this->createCopyProgram(gpu)) {
- SkDebugf("Failed to create copy program.\n");
- return false;
- }
- }
- SkASSERT(fPipelineLayout);
-
- GrVkResourceProvider& resourceProv = gpu->resourceProvider();
-
- GrVkCopyPipeline* pipeline = resourceProv.findOrCreateCopyPipeline(rt,
- fShaderStageInfo,
- fPipelineLayout->layout());
- if (!pipeline) {
- return false;
- }
-
- // UPDATE UNIFORM DESCRIPTOR SET
- int w = srcRect.width();
- int h = srcRect.height();
-
- // dst rect edges in NDC (-1 to 1)
- int dw = dst->width();
- int dh = dst->height();
- float dx0 = 2.f * dstPoint.fX / dw - 1.f;
- float dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
- float dy0 = 2.f * dstPoint.fY / dh - 1.f;
- float dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
- if (kBottomLeft_GrSurfaceOrigin == dstOrigin) {
- dy0 = -dy0;
- dy1 = -dy1;
- }
-
-
- float sx0 = (float)srcRect.fLeft;
- float sx1 = (float)(srcRect.fLeft + w);
- float sy0 = (float)srcRect.fTop;
- float sy1 = (float)(srcRect.fTop + h);
- int sh = src->height();
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- sy0 = sh - sy0;
- sy1 = sh - sy1;
- }
- // src rect edges in normalized texture space (0 to 1).
- int sw = src->width();
- sx0 /= sw;
- sx1 /= sw;
- sy0 /= sh;
- sy1 /= sh;
-
- float uniData[] = { dx1 - dx0, dy1 - dy0, dx0, dy0, // posXform
- sx1 - sx0, sy1 - sy0, sx0, sy0 }; // texCoordXform
-
- fUniformBuffer->updateData(gpu, uniData, sizeof(uniData), nullptr);
-
- const GrVkDescriptorSet* uniformDS = resourceProv.getUniformDescriptorSet();
- SkASSERT(uniformDS);
-
- VkDescriptorBufferInfo uniBufferInfo;
- uniBufferInfo.buffer = fUniformBuffer->buffer();
- uniBufferInfo.offset = fUniformBuffer->offset();
- uniBufferInfo.range = fUniformBuffer->size();
-
- VkWriteDescriptorSet descriptorWrites;
- descriptorWrites.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- descriptorWrites.pNext = nullptr;
- descriptorWrites.dstSet = uniformDS->descriptorSet();
- descriptorWrites.dstBinding = GrVkUniformHandler::kGeometryBinding;
- descriptorWrites.dstArrayElement = 0;
- descriptorWrites.descriptorCount = 1;
- descriptorWrites.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- descriptorWrites.pImageInfo = nullptr;
- descriptorWrites.pBufferInfo = &uniBufferInfo;
- descriptorWrites.pTexelBufferView = nullptr;
-
- GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
- 1,
- &descriptorWrites,
- 0, nullptr));
-
- // UPDATE SAMPLER DESCRIPTOR SET
- const GrVkDescriptorSet* samplerDS =
- gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
-
- GrSamplerState samplerState = GrSamplerState::ClampNearest();
-
- GrVkSampler* sampler = resourceProv.findOrCreateCompatibleSampler(
- samplerState, GrVkYcbcrConversionInfo());
-
- VkDescriptorImageInfo imageInfo;
- memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
- imageInfo.sampler = sampler->sampler();
- imageInfo.imageView = srcTex->textureView()->imageView();
- imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-
- VkWriteDescriptorSet writeInfo;
- memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
- writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- writeInfo.pNext = nullptr;
- writeInfo.dstSet = samplerDS->descriptorSet();
- writeInfo.dstBinding = 0;
- writeInfo.dstArrayElement = 0;
- writeInfo.descriptorCount = 1;
- writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- writeInfo.pImageInfo = &imageInfo;
- writeInfo.pBufferInfo = nullptr;
- writeInfo.pTexelBufferView = nullptr;
-
- GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
- 1,
- &writeInfo,
- 0, nullptr));
-
- VkDescriptorSet vkDescSets[] = { uniformDS->descriptorSet(), samplerDS->descriptorSet() };
-
- GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(srcTex->asRenderTarget());
- if (texRT) {
- gpu->resolveRenderTargetNoFlush(texRT);
- }
-
- // TODO: Make tighter bounds and then adjust bounds for origin and granularity if we see
- // any perf issues with using the whole bounds
- SkIRect bounds = SkIRect::MakeWH(rt->width(), rt->height());
-
- // Change layouts of rt and texture. We aren't blending so we don't need color attachment read
- // access for blending.
- GrVkImage* targetImage = rt->msaaImage() ? rt->msaaImage() : rt;
- VkAccessFlags dstAccessFlags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
- if (!canDiscardOutsideDstRect) {
- // We need to load the color attachment so need to be able to read it.
- dstAccessFlags |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
- }
- targetImage->setImageLayout(gpu,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- dstAccessFlags,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- false);
-
- srcTex->setImageLayout(gpu,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- VK_ACCESS_SHADER_READ_BIT,
- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
- false);
-
- GrStencilAttachment* stencil = rt->renderTargetPriv().getStencilAttachment();
- if (stencil) {
- GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
- // We aren't actually using the stencil but we still load and store it so we need
- // appropriate barriers.
- // TODO: Once we refactor surface and how we conntect stencil to RTs, we should not even
- // have the stencil on this render pass if possible.
- vkStencil->setImageLayout(gpu,
- VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
- VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
- false);
- }
-
- VkAttachmentLoadOp loadOp = canDiscardOutsideDstRect ? VK_ATTACHMENT_LOAD_OP_DONT_CARE
- : VK_ATTACHMENT_LOAD_OP_LOAD;
- GrVkRenderPass::LoadStoreOps vkColorOps(loadOp, VK_ATTACHMENT_STORE_OP_STORE);
- GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
- VK_ATTACHMENT_STORE_OP_STORE);
- const GrVkRenderPass* renderPass;
- const GrVkResourceProvider::CompatibleRPHandle& rpHandle = rt->compatibleRenderPassHandle();
- if (rpHandle.isValid()) {
- renderPass = gpu->resourceProvider().findRenderPass(rpHandle,
- vkColorOps,
- vkStencilOps);
- } else {
- renderPass = gpu->resourceProvider().findRenderPass(*rt,
- vkColorOps,
- vkStencilOps);
- }
-
- SkASSERT(renderPass->isCompatible(*rt->simpleRenderPass()));
-
- GrVkPrimaryCommandBuffer* cmdBuffer = gpu->currentCommandBuffer();
- cmdBuffer->beginRenderPass(gpu, renderPass, nullptr, *rt, bounds, true);
-
- GrVkSecondaryCommandBuffer* secondary = gpu->cmdPool()->findOrCreateSecondaryCommandBuffer(gpu);
- if (!secondary) {
- return false;
- }
- secondary->begin(gpu, rt->framebuffer(), renderPass);
-
- secondary->bindPipeline(gpu, pipeline);
-
- // Uniform DescriptorSet, Sampler DescriptorSet, and vertex shader uniformBuffer
- SkSTArray<3, const GrVkRecycledResource*> descriptorRecycledResources;
- descriptorRecycledResources.push_back(uniformDS);
- descriptorRecycledResources.push_back(samplerDS);
- descriptorRecycledResources.push_back(fUniformBuffer->resource());
-
- // One sampler, texture view, and texture
- SkSTArray<3, const GrVkResource*> descriptorResources;
- descriptorResources.push_back(sampler);
- descriptorResources.push_back(srcTex->textureView());
- descriptorResources.push_back(srcTex->resource());
-
- secondary->bindDescriptorSets(gpu,
- descriptorRecycledResources,
- descriptorResources,
- fPipelineLayout,
- 0,
- 2,
- vkDescSets,
- 0,
- nullptr);
-
- // Set Dynamic viewport and stencil
- // We always use one viewport the size of the RT
- VkViewport viewport;
- viewport.x = 0.0f;
- viewport.y = 0.0f;
- viewport.width = SkIntToScalar(rt->width());
- viewport.height = SkIntToScalar(rt->height());
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- secondary->setViewport(gpu, 0, 1, &viewport);
-
- // We assume the scissor is not enabled so just set it to the whole RT
- VkRect2D scissor;
- scissor.extent.width = rt->width();
- scissor.extent.height = rt->height();
- scissor.offset.x = 0;
- scissor.offset.y = 0;
- secondary->setScissor(gpu, 0, 1, &scissor);
-
- secondary->bindInputBuffer(gpu, 0, fVertexBuffer.get());
- secondary->draw(gpu, 4, 1, 0, 0);
- secondary->end(gpu);
- cmdBuffer->executeCommands(gpu, secondary);
- cmdBuffer->endRenderPass(gpu);
- secondary->unref(gpu);
-
- // Release all temp resources which should now be reffed by the cmd buffer
- pipeline->unref(gpu);
- uniformDS->unref(gpu);
- samplerDS->unref(gpu);
- sampler->unref(gpu);
- renderPass->unref(gpu);
-
- return true;
-}
-
-void GrVkCopyManager::destroyResources(GrVkGpu* gpu) {
- if (VK_NULL_HANDLE != fVertShaderModule) {
- GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fVertShaderModule,
- nullptr));
- fVertShaderModule = VK_NULL_HANDLE;
- }
-
- if (VK_NULL_HANDLE != fFragShaderModule) {
- GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fFragShaderModule,
- nullptr));
- fFragShaderModule = VK_NULL_HANDLE;
- }
-
- if (fPipelineLayout) {
- fPipelineLayout->unref(gpu);
- fPipelineLayout = nullptr;
- }
-
- if (fUniformBuffer) {
- fUniformBuffer->release(gpu);
- fUniformBuffer.reset();
- }
-}
-
-void GrVkCopyManager::abandonResources() {
- fVertShaderModule = VK_NULL_HANDLE;
- fFragShaderModule = VK_NULL_HANDLE;
- if (fPipelineLayout) {
- fPipelineLayout->unrefAndAbandon();
- fPipelineLayout = nullptr;
- }
-
- if (fUniformBuffer) {
- fUniformBuffer->abandon();
- fUniformBuffer.reset();
- }
-}
diff --git a/src/gpu/vk/GrVkCopyManager.h b/src/gpu/vk/GrVkCopyManager.h
deleted file mode 100644
index e4f02b6..0000000
--- a/src/gpu/vk/GrVkCopyManager.h
+++ /dev/null
@@ -1,54 +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 GrVkCopyManager_DEFINED
-#define GrVkCopyManager_DEFINED
-
-#include "include/gpu/GrTypes.h"
-#include "include/gpu/vk/GrVkTypes.h"
-#include "src/gpu/vk/GrVkDescriptorSetManager.h"
-
-class GrSurface;
-class GrVkCopyPipeline;
-class GrVkGpu;
-class GrVkPipelineLayout;
-class GrVkUniformBuffer;
-class GrVkVertexBuffer;
-struct SkIPoint;
-struct SkIRect;
-
-class GrVkCopyManager {
-public:
- GrVkCopyManager();
-
- ~GrVkCopyManager();
-
- bool copySurfaceAsDraw(GrVkGpu* gpu,
- GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect);
-
- void destroyResources(GrVkGpu* gpu);
- void abandonResources();
-
-private:
- bool createCopyProgram(GrVkGpu* gpu);
-
- // Everything below is only created once and shared by all copy draws/pipelines
- VkShaderModule fVertShaderModule;
- VkShaderModule fFragShaderModule;
- VkPipelineShaderStageCreateInfo fShaderStageInfo[2];
-
- GrVkDescriptorSetManager::Handle fSamplerDSHandle;
- GrVkPipelineLayout* fPipelineLayout;
-
- sk_sp<GrVkVertexBuffer> fVertexBuffer;
- std::unique_ptr<GrVkUniformBuffer> fUniformBuffer;
-};
-
-#endif
diff --git a/src/gpu/vk/GrVkCopyPipeline.cpp b/src/gpu/vk/GrVkCopyPipeline.cpp
deleted file mode 100644
index 3b44f61..0000000
--- a/src/gpu/vk/GrVkCopyPipeline.cpp
+++ /dev/null
@@ -1,202 +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 "src/gpu/vk/GrVkCopyPipeline.h"
-
-#include "include/private/SkOnce.h"
-#include "src/gpu/vk/GrVkGpu.h"
-#include "src/gpu/vk/GrVkUtil.h"
-
-#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
-#include <sanitizer/lsan_interface.h>
-#endif
-
-static void setup_multisample_state(int numSamples,
- VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
- memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
- multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
- multisampleInfo->pNext = nullptr;
- multisampleInfo->flags = 0;
- SkAssertResult(GrSampleCountToVkSampleCount(numSamples,
- &multisampleInfo->rasterizationSamples));
- multisampleInfo->sampleShadingEnable = VK_FALSE;
- multisampleInfo->minSampleShading = 0.0f;
- multisampleInfo->pSampleMask = nullptr;
- multisampleInfo->alphaToCoverageEnable = VK_FALSE;
- multisampleInfo->alphaToOneEnable = VK_FALSE;
-}
-
-GrVkCopyPipeline* GrVkCopyPipeline::Create(GrVkGpu* gpu,
- VkPipelineShaderStageCreateInfo* shaderStageInfo,
- VkPipelineLayout pipelineLayout,
- int numSamples,
- const GrVkRenderPass& renderPass,
- VkPipelineCache cache) {
-
- static const VkVertexInputAttributeDescription attributeDesc = {
- 0, // location
- 0, // binding
- VK_FORMAT_R32G32_SFLOAT, // format
- 0, // offset
- };
-
- static const VkVertexInputBindingDescription bindingDesc = {
- 0, // binding
- 2 * sizeof(float), // stride
- VK_VERTEX_INPUT_RATE_VERTEX // inputRate
- };
-
- static const VkPipelineVertexInputStateCreateInfo vertexInputInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- 1, // vertexBindingDescriptionCount
- &bindingDesc, // pVertexBindingDescriptions
- 1, // vertexAttributeDescriptionCnt
- &attributeDesc, // pVertexAttributeDescriptions
- };
-
- static const VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // topology
- VK_FALSE // primitiveRestartEnable
- };
-
- static const VkStencilOpState dummyStencilState = {
- VK_STENCIL_OP_KEEP, // failOp
- VK_STENCIL_OP_KEEP, // passOp
- VK_STENCIL_OP_KEEP, // depthFailOp
- VK_COMPARE_OP_NEVER, // compareOp
- 0, // compareMask
- 0, // writeMask
- 0 // reference
- };
-
- static const VkPipelineDepthStencilStateCreateInfo stencilInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- VK_FALSE, // depthTestEnable
- VK_FALSE, // depthWriteEnable
- VK_COMPARE_OP_ALWAYS, // depthCompareOp
- VK_FALSE, // depthBoundsTestEnable
- VK_FALSE, // stencilTestEnable
- dummyStencilState, // front
- dummyStencilState, // bakc
- 0.0f, // minDepthBounds
- 1.0f // maxDepthBounds
- };
-
- static const VkPipelineViewportStateCreateInfo viewportInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- 1, // viewportCount
- nullptr, // pViewports
- 1, // scissorCount
- nullptr // pScissors
- };
-
- static const VkPipelineColorBlendAttachmentState attachmentState = {
- VK_FALSE, // blendEnable
- VK_BLEND_FACTOR_ONE, // srcColorBlendFactor
- VK_BLEND_FACTOR_ZERO, // dstColorBlendFactor
- VK_BLEND_OP_ADD, // colorBlendOp
- VK_BLEND_FACTOR_ONE, // srcAlphaBlendFactor
- VK_BLEND_FACTOR_ZERO, // dstAlphaBlendFactor
- VK_BLEND_OP_ADD, // alphaBlendOp
- VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // colorWriteMask
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT // colorWriteMask
- };
-
- static const VkPipelineColorBlendStateCreateInfo colorBlendInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- VK_FALSE, // logicOpEnable
- VK_LOGIC_OP_CLEAR, // logicOp
- 1, // attachmentCount
- &attachmentState, // pAttachments
- { 0.f, 0.f, 0.f, 0.f } // blendConstants[4]
- };
-
- static const VkPipelineRasterizationStateCreateInfo rasterInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- VK_FALSE, // depthClampEnable
- VK_FALSE, // rasterizerDiscardEnabled
- VK_POLYGON_MODE_FILL, // polygonMode
- VK_CULL_MODE_NONE, // cullMode
- VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
- VK_FALSE, // depthBiasEnable
- 0.0f, // depthBiasConstantFactor
- 0.0f, // depthBiasClamp
- 0.0f, // depthBiasSlopeFactor
- 1.0f // lineWidth
- };
-
- static const VkDynamicState dynamicStates[2] = { VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR };
- static const VkPipelineDynamicStateCreateInfo dynamicInfo = {
- VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- 2, // dynamicStateCount
- dynamicStates // pDynamicStates
- };
-
- VkPipelineMultisampleStateCreateInfo multisampleInfo;
- setup_multisample_state(numSamples, &multisampleInfo);
-
- VkGraphicsPipelineCreateInfo pipelineCreateInfo;
- memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
- pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
- pipelineCreateInfo.pNext = nullptr;
- pipelineCreateInfo.flags = 0;
- pipelineCreateInfo.stageCount = 2;
- pipelineCreateInfo.pStages = shaderStageInfo;
- pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
- pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
- pipelineCreateInfo.pTessellationState = nullptr;
- pipelineCreateInfo.pViewportState = &viewportInfo;
- pipelineCreateInfo.pRasterizationState = &rasterInfo;
- pipelineCreateInfo.pMultisampleState = &multisampleInfo;
- pipelineCreateInfo.pDepthStencilState = &stencilInfo;
- pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
- pipelineCreateInfo.pDynamicState = &dynamicInfo;
- pipelineCreateInfo.layout = pipelineLayout;
- pipelineCreateInfo.renderPass = renderPass.vkRenderPass();
- pipelineCreateInfo.subpass = 0;
- pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
- pipelineCreateInfo.basePipelineIndex = -1;
-
- VkPipeline vkPipeline;
- VkResult err;
- {
-#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
- // skia:8712
- __lsan::ScopedDisabler lsanDisabler;
-#endif
- err = GR_VK_CALL(gpu->vkInterface(), CreateGraphicsPipelines(gpu->device(),
- cache, 1,
- &pipelineCreateInfo,
- nullptr, &vkPipeline));
- }
- if (err) {
- SkDebugf("Failed to create copy pipeline. Error: %d\n", err);
- return nullptr;
- }
-
- return new GrVkCopyPipeline(vkPipeline, &renderPass);
-}
-
-bool GrVkCopyPipeline::isCompatible(const GrVkRenderPass& rp) const {
- return rp.isCompatible(*fRenderPass);
-}
diff --git a/src/gpu/vk/GrVkCopyPipeline.h b/src/gpu/vk/GrVkCopyPipeline.h
deleted file mode 100644
index 9b8d2d2..0000000
--- a/src/gpu/vk/GrVkCopyPipeline.h
+++ /dev/null
@@ -1,43 +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 GrVkCopyPipeline_DEFINED
-#define GrVkCopyPipeline_DEFINED
-
-#include "src/gpu/vk/GrVkPipeline.h"
-
-class GrVkCopyPipeline : public GrVkPipeline {
-public:
- // We expect the passed in renderPass to be stored on the GrVkResourceProvider and not a local
- // object of the client.
- static GrVkCopyPipeline* Create(GrVkGpu* gpu,
- VkPipelineShaderStageCreateInfo* shaderStageInfo,
- VkPipelineLayout pipelineLayout,
- int numSamples,
- const GrVkRenderPass& renderPass,
- VkPipelineCache cache);
-
- bool isCompatible(const GrVkRenderPass& rp) const;
-
-#ifdef SK_TRACE_VK_RESOURCES
- void dumpInfo() const override {
- SkDebugf("GrVkCopyPipeline: %d (%d refs)\n", fPipeline, this->getRefCnt());
- }
-#endif
-
-private:
- GrVkCopyPipeline(VkPipeline pipeline, const GrVkRenderPass* renderPass)
- : INHERITED(pipeline)
- , fRenderPass(renderPass) {
- }
-
- const GrVkRenderPass* fRenderPass;
-
- typedef GrVkPipeline INHERITED;
-};
-
-#endif
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 9b4d019..8a5f979 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -262,9 +262,6 @@
}
fSemaphoresToSignal.reset();
-
- fCopyManager.destroyResources(this);
-
// must call this just before we destroy the command pool and VkDevice
fResourceProvider.destroyResources(VK_ERROR_DEVICE_LOST == res);
@@ -299,7 +296,6 @@
for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
fSemaphoresToSignal[i]->unrefAndAbandon();
}
- fCopyManager.abandonResources();
// must call this just before we destroy the command pool and VkDevice
fResourceProvider.abandonResources();
@@ -785,6 +781,11 @@
// R8G8B8A8_UNORM image and then copy it.
sk_sp<GrVkTexture> copyTexture;
if (dataColorType == GrColorType::kRGB_888x && tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
+ bool dstHasYcbcr = tex->ycbcrConversionInfo().isValid();
+ if (!this->vkCaps().canCopyAsBlit(tex->config(), 1, false, dstHasYcbcr,
+ kRGBA_8888_GrPixelConfig, 1, false, false)) {
+ return false;
+ }
GrSurfaceDesc surfDesc;
surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
surfDesc.fWidth = width;
@@ -813,16 +814,6 @@
return false;
}
- bool dstHasYcbcr = tex->ycbcrConversionInfo().isValid();
- if (!this->vkCaps().canCopyAsBlit(tex->config(), 1, false, dstHasYcbcr,
- copyTexture->config(), 1, false,
- false) &&
- !this->vkCaps().canCopyAsDraw(tex->config(), SkToBool(tex->asRenderTarget()),
- dstHasYcbcr,
- copyTexture->config(), true, false)) {
- return false;
- }
-
uploadTexture = copyTexture.get();
uploadLeft = 0;
uploadTop = 0;
@@ -883,10 +874,8 @@
// now.
if (copyTexture.get()) {
SkASSERT(dataColorType == GrColorType::kRGB_888x);
- static const GrSurfaceOrigin kOrigin = kTopLeft_GrSurfaceOrigin;
- SkAssertResult(this->copySurface(tex, kOrigin, copyTexture.get(), kOrigin,
- SkIRect::MakeWH(width, height), SkIPoint::Make(left, top),
- false));
+ SkAssertResult(this->copySurface(tex, copyTexture.get(), SkIRect::MakeWH(width, height),
+ SkIPoint::Make(left, top), false));
}
if (1 == mipLevelCount) {
tex->texturePriv().markMipMapsDirty();
@@ -2068,19 +2057,16 @@
return 0;
}
-void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- GrVkImage* dstImage,
- GrVkImage* srcImage,
- const SkIRect& srcRect,
+void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, GrSurface* src, GrVkImage* dstImage,
+ GrVkImage* srcImage, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
#ifdef SK_DEBUG
int dstSampleCnt = get_surface_sample_cnt(dst);
int srcSampleCnt = get_surface_sample_cnt(src);
bool dstHasYcbcr = dstImage->ycbcrConversionInfo().isValid();
bool srcHasYcbcr = srcImage->ycbcrConversionInfo().isValid();
- SkASSERT(this->vkCaps().canCopyImage(dst->config(), dstSampleCnt, dstOrigin, dstHasYcbcr,
- src->config(), srcSampleCnt, srcOrigin, srcHasYcbcr));
+ SkASSERT(this->vkCaps().canCopyImage(dst->config(), dstSampleCnt, dstHasYcbcr,
+ src->config(), srcSampleCnt, srcHasYcbcr));
#endif
@@ -2098,24 +2084,13 @@
VK_PIPELINE_STAGE_TRANSFER_BIT,
false);
- // Flip rect if necessary
- SkIRect srcVkRect = srcRect;
- int32_t dstY = dstPoint.fY;
-
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- SkASSERT(kBottomLeft_GrSurfaceOrigin == dstOrigin);
- srcVkRect.fTop = src->height() - srcRect.fBottom;
- srcVkRect.fBottom = src->height() - srcRect.fTop;
- dstY = dst->height() - dstPoint.fY - srcVkRect.height();
- }
-
VkImageCopy copyRegion;
memset(©Region, 0, sizeof(VkImageCopy));
copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
- copyRegion.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
+ copyRegion.srcOffset = { srcRect.fLeft, srcRect.fTop, 0 };
copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
- copyRegion.dstOffset = { dstPoint.fX, dstY, 0 };
- copyRegion.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 };
+ copyRegion.dstOffset = { dstPoint.fX, dstPoint.fY, 0 };
+ copyRegion.extent = { (uint32_t)srcRect.width(), (uint32_t)srcRect.height(), 1 };
fCurrentCmdBuffer->copyImage(this,
srcImage,
@@ -2127,14 +2102,12 @@
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
srcRect.width(), srcRect.height());
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
+ // The rect is already in device space so we pass in kTopLeft so no flip is done.
+ this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
}
-void GrVkGpu::copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- GrVkImage* dstImage,
- GrVkImage* srcImage,
- const SkIRect& srcRect,
+void GrVkGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, GrVkImage* dstImage,
+ GrVkImage* srcImage, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
#ifdef SK_DEBUG
int dstSampleCnt = get_surface_sample_cnt(dst);
@@ -2159,40 +2132,14 @@
false);
// Flip rect if necessary
- SkIRect srcVkRect;
- srcVkRect.fLeft = srcRect.fLeft;
- srcVkRect.fRight = srcRect.fRight;
- SkIRect dstRect;
- dstRect.fLeft = dstPoint.fX;
- dstRect.fRight = dstPoint.fX + srcRect.width();
-
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- srcVkRect.fTop = src->height() - srcRect.fBottom;
- srcVkRect.fBottom = src->height() - srcRect.fTop;
- } else {
- srcVkRect.fTop = srcRect.fTop;
- srcVkRect.fBottom = srcRect.fBottom;
- }
-
- if (kBottomLeft_GrSurfaceOrigin == dstOrigin) {
- dstRect.fTop = dst->height() - dstPoint.fY - srcVkRect.height();
- } else {
- dstRect.fTop = dstPoint.fY;
- }
- dstRect.fBottom = dstRect.fTop + srcVkRect.height();
-
- // If we have different origins, we need to flip the top and bottom of the dst rect so that we
- // get the correct origintation of the copied data.
- if (srcOrigin != dstOrigin) {
- using std::swap;
- swap(dstRect.fTop, dstRect.fBottom);
- }
+ SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, srcRect.width(),
+ srcRect.height());
VkImageBlit blitRegion;
memset(&blitRegion, 0, sizeof(VkImageBlit));
blitRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
- blitRegion.srcOffsets[0] = { srcVkRect.fLeft, srcVkRect.fTop, 0 };
- blitRegion.srcOffsets[1] = { srcVkRect.fRight, srcVkRect.fBottom, 1 };
+ blitRegion.srcOffsets[0] = { srcRect.fLeft, srcRect.fTop, 0 };
+ blitRegion.srcOffsets[1] = { srcRect.fRight, srcRect.fBottom, 1 };
blitRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
blitRegion.dstOffsets[0] = { dstRect.fLeft, dstRect.fTop, 0 };
blitRegion.dstOffsets[1] = { dstRect.fRight, dstRect.fBottom, 1 };
@@ -2204,32 +2151,22 @@
&blitRegion,
VK_FILTER_NEAREST); // We never scale so any filter works here
- dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, srcRect.width(), srcRect.height());
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
+ // The rect is already in device space so we pass in kTopLeft so no flip is done.
+ this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
}
-void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
- GrSurfaceOrigin srcOrigin, const SkIRect& origSrcRect,
- const SkIPoint& origDstPoint) {
+void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint) {
GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget());
- SkIRect srcRect = origSrcRect;
- SkIPoint dstPoint = origDstPoint;
- if (kBottomLeft_GrSurfaceOrigin == srcOrigin) {
- SkASSERT(kBottomLeft_GrSurfaceOrigin == dstOrigin);
- srcRect = {origSrcRect.fLeft, src->height() - origSrcRect.fBottom,
- origSrcRect.fRight, src->height() - origSrcRect.fTop};
- dstPoint.fY = dst->height() - dstPoint.fY - srcRect.height();
- }
this->resolveImage(dst, srcRT, srcRect, dstPoint);
- SkIRect dstRect = SkIRect::MakeXYWH(origDstPoint.fX, origDstPoint.fY,
+ SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
srcRect.width(), srcRect.height());
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
+ // The rect is already in device space so we pass in kTopLeft so no flip is done.
+ this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
}
-bool GrVkGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint,
- bool canDiscardOutsideDstRect) {
+bool GrVkGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) {
#ifdef SK_DEBUG
if (GrVkRenderTarget* srcRT = static_cast<GrVkRenderTarget*>(src->asRenderTarget())) {
SkASSERT(!srcRT->wrapsSecondaryCommandBuffer());
@@ -2270,33 +2207,22 @@
bool dstHasYcbcr = dstImage->ycbcrConversionInfo().isValid();
bool srcHasYcbcr = srcImage->ycbcrConversionInfo().isValid();
- if (this->vkCaps().canCopyAsResolve(dstConfig, dstSampleCnt, dstOrigin, dstHasYcbcr,
- srcConfig, srcSampleCnt, srcOrigin, srcHasYcbcr)) {
- this->copySurfaceAsResolve(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
+ if (this->vkCaps().canCopyAsResolve(dstConfig, dstSampleCnt, dstHasYcbcr,
+ srcConfig, srcSampleCnt, srcHasYcbcr)) {
+ this->copySurfaceAsResolve(dst, src, srcRect, dstPoint);
return true;
}
- if (this->vkCaps().canCopyAsDraw(dstConfig, SkToBool(dst->asRenderTarget()), dstHasYcbcr,
- srcConfig, SkToBool(src->asTexture()), srcHasYcbcr)) {
- SkAssertResult(fCopyManager.copySurfaceAsDraw(this, dst, dstOrigin, src, srcOrigin, srcRect,
- dstPoint, canDiscardOutsideDstRect));
- auto dstRect = srcRect.makeOffset(dstPoint.fX, dstPoint.fY);
- this->didWriteToSurface(dst, dstOrigin, &dstRect);
- return true;
- }
-
- if (this->vkCaps().canCopyImage(dstConfig, dstSampleCnt, dstOrigin, dstHasYcbcr,
- srcConfig, srcSampleCnt, srcOrigin, srcHasYcbcr)) {
- this->copySurfaceAsCopyImage(dst, dstOrigin, src, srcOrigin, dstImage, srcImage,
- srcRect, dstPoint);
+ if (this->vkCaps().canCopyImage(dstConfig, dstSampleCnt, dstHasYcbcr,
+ srcConfig, srcSampleCnt, srcHasYcbcr)) {
+ this->copySurfaceAsCopyImage(dst, src, dstImage, srcImage, srcRect, dstPoint);
return true;
}
if (this->vkCaps().canCopyAsBlit(dstConfig, dstSampleCnt, dstImage->isLinearTiled(),
dstHasYcbcr, srcConfig, srcSampleCnt,
srcImage->isLinearTiled(), srcHasYcbcr)) {
- this->copySurfaceAsBlit(dst, dstOrigin, src, srcOrigin, dstImage, srcImage,
- srcRect, dstPoint);
+ this->copySurfaceAsBlit(dst, src, dstImage, srcImage, srcRect, dstPoint);
return true;
}
@@ -2346,6 +2272,17 @@
if (dstColorType == GrColorType::kRGB_888x && image->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
SkASSERT(surface->config() == kRGB_888_GrPixelConfig);
+ int srcSampleCount = 0;
+ if (rt) {
+ srcSampleCount = rt->numColorSamples();
+ }
+ bool srcHasYcbcr = image->ycbcrConversionInfo().isValid();
+ if (!this->vkCaps().canCopyAsBlit(kRGBA_8888_GrPixelConfig, 1, false, false,
+ surface->config(), srcSampleCount, image->isLinearTiled(),
+ srcHasYcbcr)) {
+ return false;
+ }
+
// Make a new surface that is RGBA to copy the RGB surface into.
GrSurfaceDesc surfDesc;
surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
@@ -2376,25 +2313,9 @@
return false;
}
- int srcSampleCount = 0;
- if (rt) {
- srcSampleCount = rt->numColorSamples();
- }
- bool srcHasYcbcr = image->ycbcrConversionInfo().isValid();
- if (!this->vkCaps().canCopyAsBlit(copySurface->config(), 1, false, false,
- surface->config(), srcSampleCount, image->isLinearTiled(),
- srcHasYcbcr) &&
- !this->vkCaps().canCopyAsDraw(copySurface->config(), false, false,
- surface->config(), SkToBool(surface->asTexture()),
- srcHasYcbcr)) {
- return false;
- }
SkIRect srcRect = SkIRect::MakeXYWH(left, top, width, height);
- static const GrSurfaceOrigin kOrigin = kTopLeft_GrSurfaceOrigin;
- if (!this->copySurface(copySurface.get(), kOrigin, surface, kOrigin,
- srcRect, SkIPoint::Make(0,0))) {
- return false;
- }
+ SkAssertResult(this->copySurface(copySurface.get(), surface, srcRect, SkIPoint::Make(0,0)));
+
top = 0;
left = 0;
dstColorType = GrColorType::kRGBA_8888;
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 820d801..d1b2d98 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -12,7 +12,6 @@
#include "include/gpu/vk/GrVkTypes.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/vk/GrVkCaps.h"
-#include "src/gpu/vk/GrVkCopyManager.h"
#include "src/gpu/vk/GrVkIndexBuffer.h"
#include "src/gpu/vk/GrVkMemory.h"
#include "src/gpu/vk/GrVkResourceProvider.h"
@@ -222,8 +221,7 @@
bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
GrColorType, GrGpuBuffer* transferBuffer, size_t offset) override;
- bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
- GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+ bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override;
void onFinishFlush(GrSurfaceProxy*[], int, SkSurface::BackendSurfaceAccess access,
@@ -240,21 +238,14 @@
void internalResolveRenderTarget(GrRenderTarget*, bool requiresSubmit);
- void copySurfaceAsCopyImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- GrVkImage* dstImage, GrVkImage* srcImage,
- const SkIRect& srcRect,
+ void copySurfaceAsCopyImage(GrSurface* dst, GrSurface* src, GrVkImage* dstImage,
+ GrVkImage* srcImage, const SkIRect& srcRect,
const SkIPoint& dstPoint);
- void copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- GrVkImage* dstImage, GrVkImage* srcImage,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint);
+ void copySurfaceAsBlit(GrSurface* dst, GrSurface* src, GrVkImage* dstImage, GrVkImage* srcImage,
+ const SkIRect& srcRect, const SkIPoint& dstPoint);
- void copySurfaceAsResolve(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
+ void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint);
// helpers for onCreateTexture and writeTexturePixels
@@ -298,8 +289,6 @@
VkPhysicalDeviceProperties fPhysDevProps;
VkPhysicalDeviceMemoryProperties fPhysDevMemProps;
- GrVkCopyManager fCopyManager;
-
// compiler used for compiling sksl into spirv. We only want to create the compiler once since
// there is significant overhead to the first compile of any compiler.
SkSL::Compiler* fCompiler;
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index c95f1e5..726095d 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -46,23 +46,19 @@
class Copy : public GrVkPrimaryCommandBufferTask {
public:
- Copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint, bool shouldDiscardDst)
+ Copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint, bool shouldDiscardDst)
: fSrc(src)
- , fSrcOrigin(srcOrigin)
, fSrcRect(srcRect)
, fDstPoint(dstPoint)
, fShouldDiscardDst(shouldDiscardDst) {}
void execute(const Args& args) override {
- args.fGpu->copySurface(args.fSurface, args.fOrigin, fSrc.get(), fSrcOrigin, fSrcRect,
- fDstPoint, fShouldDiscardDst);
+ args.fGpu->copySurface(args.fSurface, fSrc.get(), fSrcRect, fDstPoint, fShouldDiscardDst);
}
private:
using Src = GrPendingIOResource<GrSurface, kRead_GrIOType>;
Src fSrc;
- GrSurfaceOrigin fSrcOrigin;
SkIRect fSrcRect;
SkIPoint fDstPoint;
bool fShouldDiscardDst;
@@ -94,9 +90,9 @@
/////////////////////////////////////////////////////////////////////////////
-void GrVkGpuTextureCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
- fTasks.emplace<Copy>(src, srcOrigin, srcRect, dstPoint, false);
+void GrVkGpuTextureCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
+ const SkIPoint& dstPoint) {
+ fTasks.emplace<Copy>(src, srcRect, dstPoint, false);
}
void GrVkGpuTextureCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
@@ -109,7 +105,7 @@
}
void GrVkGpuTextureCommandBuffer::submit() {
- GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fTexture, fOrigin};
+ GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fTexture};
for (auto& task : fTasks) {
task.execute(taskArgs);
}
@@ -231,7 +227,7 @@
GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment();
auto currPreCmd = fPreCommandBufferTasks.begin();
- GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fRenderTarget, fOrigin};
+ GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fRenderTarget};
for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
@@ -604,7 +600,7 @@
++fCommandBufferInfos[fCurrentCmdInfo].fNumPreCmds;
}
-void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+void GrVkGpuRTCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
if (!cbInfo.fIsEmpty || LoadStoreState::kStartsWithClear == cbInfo.fLoadStoreState) {
@@ -612,8 +608,7 @@
}
fPreCommandBufferTasks.emplace<Copy>(
- src, srcOrigin, srcRect, dstPoint,
- LoadStoreState::kStartsWithDiscard == cbInfo.fLoadStoreState);
+ src, srcRect, dstPoint, LoadStoreState::kStartsWithDiscard == cbInfo.fLoadStoreState);
++fCommandBufferInfos[fCurrentCmdInfo].fNumPreCmds;
if (LoadStoreState::kLoadAndStore != cbInfo.fLoadStoreState) {
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h
index 76c1284..395ae24 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.h
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.h
@@ -31,7 +31,6 @@
struct Args {
GrGpu* fGpu;
GrSurface* fSurface;
- GrSurfaceOrigin fOrigin;
};
virtual void execute(const Args& args) = 0;
@@ -46,8 +45,7 @@
public:
GrVkGpuTextureCommandBuffer(GrVkGpu* gpu) : fGpu(gpu) {}
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override;
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) override;
@@ -81,8 +79,7 @@
void inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) override;
- void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint) override;
+ void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
GrGpuBuffer* transferBuffer, size_t offset) override;
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 87f653e..81cd3a6 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -12,7 +12,6 @@
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/vk/GrVkCommandBuffer.h"
#include "src/gpu/vk/GrVkCommandPool.h"
-#include "src/gpu/vk/GrVkCopyPipeline.h"
#include "src/gpu/vk/GrVkGpu.h"
#include "src/gpu/vk/GrVkPipeline.h"
#include "src/gpu/vk/GrVkRenderTarget.h"
@@ -107,33 +106,6 @@
shaderStageCount, primitiveType, compatibleRenderPass, layout, this->pipelineCache());
}
-GrVkCopyPipeline* GrVkResourceProvider::findOrCreateCopyPipeline(
- const GrVkRenderTarget* dst,
- VkPipelineShaderStageCreateInfo* shaderStageInfo,
- VkPipelineLayout pipelineLayout) {
- // Find or Create a compatible pipeline
- GrVkCopyPipeline* pipeline = nullptr;
- for (int i = 0; i < fCopyPipelines.count() && !pipeline; ++i) {
- if (fCopyPipelines[i]->isCompatible(*dst->simpleRenderPass())) {
- pipeline = fCopyPipelines[i];
- }
- }
- if (!pipeline) {
- pipeline = GrVkCopyPipeline::Create(fGpu, shaderStageInfo,
- pipelineLayout,
- dst->numColorSamples(),
- *dst->simpleRenderPass(),
- this->pipelineCache());
- if (!pipeline) {
- return nullptr;
- }
- fCopyPipelines.push_back(pipeline);
- }
- SkASSERT(pipeline);
- pipeline->ref();
- return pipeline;
-}
-
// To create framebuffers, we first need to create a simple RenderPass that is
// only used for framebuffer creation. When we actually render we will create
// RenderPasses as needed that are compatible with the framebuffer.
@@ -404,11 +376,6 @@
taskGroup->wait();
}
- // Release all copy pipelines
- for (int i = 0; i < fCopyPipelines.count(); ++i) {
- fCopyPipelines[i]->unref(fGpu);
- }
-
// loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
for (int i = 0; i < fRenderPassArray.count(); ++i) {
fRenderPassArray[i].releaseResources(fGpu);
@@ -477,11 +444,6 @@
}
fAvailableCommandPools.reset();
- // Abandon all copy pipelines
- for (int i = 0; i < fCopyPipelines.count(); ++i) {
- fCopyPipelines[i]->unrefAndAbandon();
- }
-
// loop over all render pass sets to make sure we destroy all the internal VkRenderPasses
for (int i = 0; i < fRenderPassArray.count(); ++i) {
fRenderPassArray[i].abandonResources();
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 3df1a4d..649d461 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -27,7 +27,6 @@
#include <thread>
class GrVkCommandPool;
-class GrVkCopyPipeline;
class GrVkGpu;
class GrVkPipeline;
class GrVkPipelineState;
@@ -55,10 +54,6 @@
VkRenderPass compatibleRenderPass,
VkPipelineLayout layout);
- GrVkCopyPipeline* findOrCreateCopyPipeline(const GrVkRenderTarget* dst,
- VkPipelineShaderStageCreateInfo*,
- VkPipelineLayout);
-
GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle);
// Finds or creates a simple render pass that matches the target, increments the refcount,
@@ -269,9 +264,6 @@
// Central cache for creating pipelines
VkPipelineCache fPipelineCache;
- // Cache of previously created copy pipelines
- SkTArray<GrVkCopyPipeline*> fCopyPipelines;
-
SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
SkTArray<const GrVkRenderPass*> fExternalRenderPasses;