diff options
-rw-r--r-- | src/gpu/GrGpu.cpp | 78 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 76 | ||||
-rw-r--r-- | src/gpu/GrOpFlushState.cpp | 31 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 85 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 3 | ||||
-rw-r--r-- | src/gpu/mock/GrMockGpu.h | 5 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlGpu.h | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 48 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 3 |
9 files changed, 4 insertions, 331 deletions
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 8d0cb7f4bb..083a125bab 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -214,84 +214,6 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, canDiscardOutsideDstRect); } -bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, - int height, GrColorType srcColorType, - GrSRGBConversion srgbConversion, DrawPreference* drawPreference, - WritePixelTempDrawInfo* tempDrawInfo) { - SkASSERT(drawPreference); - SkASSERT(tempDrawInfo); - SkASSERT(dstSurface); - SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference); - - GrPixelConfig tempSurfaceConfig = kUnknown_GrPixelConfig; - // GrGpu::writePixels doesn't do any sRGB conversions, so we must draw if there is one. - switch (srgbConversion) { - case GrSRGBConversion::kNone: - // We support writing just A to a RGBA. In that case there is no sRGB version of the - // src format but we still want to succeed. - if (GrColorTypeIsAlphaOnly(srcColorType)) { - tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kNo); - } else { - tempSurfaceConfig = GrColorTypeToPixelConfig( - srcColorType, GrPixelConfigIsSRGBEncoded(dstSurface->config())); - } - break; - case GrSRGBConversion::kLinearToSRGB: - SkASSERT(this->caps()->srgbSupport()); - // This assert goes away when we start referring to CPU data using color type. - tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kNo); - // We don't currently support storing sRGB encoded data in a surface unless it is - // an SRGB-encoded config. That is likely to change when we need to store sRGB encoded - // data in 101010102 and F16 textures. We'll have to provoke the caller to do the - // conversion in a shader. - if (!GrPixelConfigIsSRGB(dstSurface->config())) { - return false; - } - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - break; - case GrSRGBConversion::kSRGBToLinear: - SkASSERT(this->caps()->srgbSupport()); - tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kYes); - // Currently we don't expect to make a SRGB encoded surface and then succeed at - // treating it as though it were linear and then convert to sRGB. - if (GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(dstSurface->config())) { - return false; - } - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - break; - } - if (kUnknown_GrPixelConfig == tempSurfaceConfig) { - return false; - } - - // Default values for intermediate draws. The intermediate texture config matches the dst's - // config, is approx sized to the write rect, no swizzling or sppofing of the src config. - tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags; - tempDrawInfo->fTempSurfaceDesc.fConfig = tempSurfaceConfig; - tempDrawInfo->fTempSurfaceDesc.fWidth = width; - tempDrawInfo->fTempSurfaceDesc.fHeight = height; - tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1; - tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); - tempDrawInfo->fWriteColorType = srcColorType; - - if (!this->onGetWritePixelsInfo(dstSurface, dstOrigin, width, height, srcColorType, - drawPreference, tempDrawInfo)) { - return false; - } - - // Check to see if we're going to request that the caller draw when drawing is not possible. - if (!dstSurface->asRenderTarget() || - !this->caps()->isConfigTexturable(tempDrawInfo->fTempSurfaceDesc.fConfig)) { - // If we don't have a fallback to a straight upload then fail. - if (kRequireDraw_DrawPreference == *drawPreference /*TODO || - !this->caps()->isConfigTexturable(srcConfig)*/) { - return false; - } - *drawPreference = kNoDraw_DrawPreference; - } - return true; -} - bool GrGpu::readPixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, int width, int height, GrColorType dstColorType, void* buffer, size_t rowBytes) { SkASSERT(surface); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 7c92795c50..6adabf46d1 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -141,69 +141,6 @@ public: */ void resolveRenderTarget(GrRenderTarget*); - /** Describes why an intermediate draw must/should be performed before readPixels. */ - enum DrawPreference { - /** - * On input means that the caller would proceed without draw if the GrGpu doesn't request - * one. On output means that the GrGpu is not requesting a draw. - */ - kNoDraw_DrawPreference, - /** - * Means that the client would prefer a draw for performance of the readback but - * can satisfy a straight readPixels call on the inputs without an intermediate draw. - * getReadPixelsInfo will never set the draw preference to this value but may leave - * it set. - */ - kCallerPrefersDraw_DrawPreference, - /** - * On output means that GrGpu would prefer a draw for performance of the readback but - * can satisfy a straight readPixels call on the inputs without an intermediate draw. The - * caller of getReadPixelsInfo should never specify this on intput. - */ - kGpuPrefersDraw_DrawPreference, - /** - * On input means that the caller requires a draw to do a transformation and there is no - * CPU fallback. On output means that GrGpu can only satisfy the readPixels request if the - * intermediate draw is performed. - */ - kRequireDraw_DrawPreference - }; - - /** - * Info struct returned by getWritePixelsInfo about performing an intermediate draw in order - * to write pixels to a GrSurface for either performance or correctness reasons. - */ - struct WritePixelTempDrawInfo { - /** - * If the GrGpu is requesting that the caller upload to an intermediate surface and draw - * that to the dst then this is the descriptor for the intermediate surface. The caller - * should upload the pixels such that the upper left pixel of the upload rect is at 0,0 in - * the intermediate surface - */ - GrSurfaceDesc fTempSurfaceDesc; - /** - * Swizzle to apply during the draw. This is used to compensate for either feature or - * performance limitations in the underlying 3D API. - */ - GrSwizzle fSwizzle; - /** - * The color type that should be specified when uploading the *original* data to the temp - * surface before the draw. This may be different than the original src color type in - * order to compensate for swizzling that will occur when drawing. The original gamma - * encoding is always used. - */ - GrColorType fWriteColorType; - }; - - /** - * Used to negotiate whether and how an intermediate surface should be used to write pixels to - * a GrSurface. If this returns false then GrGpu could not deduce an intermediate draw - * that would allow a successful transfer of the src pixels to the dst. The passed width, - * height, and rowBytes, must be non-zero and already reflect clipping to the dst bounds. - */ - bool getWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrColorType, - GrSRGBConversion, DrawPreference*, WritePixelTempDrawInfo*); - /** * Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed. * @@ -472,16 +409,6 @@ public: } protected: - static void ElevateDrawPreference(GrGpu::DrawPreference* preference, - GrGpu::DrawPreference elevation) { - GR_STATIC_ASSERT(GrGpu::kCallerPrefersDraw_DrawPreference > GrGpu::kNoDraw_DrawPreference); - GR_STATIC_ASSERT(GrGpu::kGpuPrefersDraw_DrawPreference > - GrGpu::kCallerPrefersDraw_DrawPreference); - GR_STATIC_ASSERT(GrGpu::kRequireDraw_DrawPreference > - GrGpu::kGpuPrefersDraw_DrawPreference); - *preference = SkTMax(*preference, elevation); - } - // Handles cases where a surface will be updated without a call to flushRenderTarget. void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds, uint32_t mipLevels = 1) const; @@ -517,9 +444,6 @@ private: virtual GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern, const void* data) = 0; - virtual bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, - GrColorType, DrawPreference*, WritePixelTempDrawInfo*) = 0; - // overridden by backend-specific derived class to perform the surface read virtual bool onReadPixels(GrSurface*, GrSurfaceOrigin, int left, int top, int width, int height, GrColorType, void* buffer, size_t rowBytes) = 0; diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp index 661d9aaa76..94a021d90a 100644 --- a/src/gpu/GrOpFlushState.cpp +++ b/src/gpu/GrOpFlushState.cpp @@ -83,36 +83,13 @@ void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload) { int width, int height, GrColorType srcColorType, const void* buffer, size_t rowBytes) { - // We don't allow srgb conversions via op flush state uploads. - static constexpr auto kSRGBConversion = GrSRGBConversion::kNone; GrSurface* dstSurface = dstProxy->priv().peekSurface(); - GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference; - GrGpu::WritePixelTempDrawInfo tempInfo; - if (!fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(), width, height, srcColorType, - kSRGBConversion, &drawPreference, &tempInfo)) { + if (!fGpu->caps()->surfaceSupportsWritePixels(dstSurface) && + fGpu->caps()->supportedWritePixelsColorType(dstSurface->config(), srcColorType) != srcColorType) { return false; } - if (GrGpu::kNoDraw_DrawPreference == drawPreference) { - return this->fGpu->writePixels(dstSurface, dstProxy->origin(), left, top, width, height, - srcColorType, buffer, rowBytes); - } - // TODO: Shouldn't we be bailing here if a draw is really required instead of a copy? - // e.g. if (tempInfo.fSwizzle != "RGBA") fail. - GrSurfaceDesc desc; - desc.fWidth = width; - desc.fHeight = height; - desc.fConfig = dstProxy->config(); - sk_sp<GrTexture> temp(this->fResourceProvider->createApproxTexture( - desc, GrResourceProvider::kNoPendingIO_Flag)); - if (!temp) { - return false; - } - if (!fGpu->writePixels(temp.get(), dstProxy->origin(), 0, 0, width, height, - tempInfo.fWriteColorType, buffer, rowBytes)) { - return false; - } - return fGpu->copySurface(dstSurface, dstProxy->origin(), temp.get(), dstProxy->origin(), - SkIRect::MakeWH(width, height), {left, top}); + return this->fGpu->writePixels(dstSurface, dstProxy->origin(), left, top, width, height, + srcColorType, buffer, rowBytes); }; upload(wp); } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index f73a3138af..41d74e78ff 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -648,91 +648,6 @@ sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBacken return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0); } -//////////////////////////////////////////////////////////////////////////////// - -bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, - int height, GrColorType srcColorType, - DrawPreference* drawPreference, - WritePixelTempDrawInfo* tempDrawInfo) { - // We don't want to introduce a sRGB conversion if we trigger a draw. - auto srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(dstSurface->config()); - if (*drawPreference != kNoDraw_DrawPreference) { - // We assume the base class has only inserted a draw for sRGB reasons. So the temp surface - // has the config of the original src data. There is no swizzling nor src config spoofing. - SkASSERT(tempDrawInfo->fWriteColorType == srcColorType); - SkASSERT(GrPixelConfigToColorType(tempDrawInfo->fTempSurfaceDesc.fConfig) == srcColorType); - SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA()); - // Don't undo a sRGB conversion introduced by our caller via an intermediate draw. - srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(tempDrawInfo->fTempSurfaceDesc.fConfig); - } - if (GrColorTypeIsAlphaOnly(srcColorType)) { - srcConfigSRGBEncoded = GrSRGBEncoded::kNo; - } - - if (SkToBool(dstSurface->asRenderTarget())) { - if (this->glCaps().useDrawInsteadOfAllRenderTargetWrites()) { - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - } - } - - GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture()); - - if (texture) { - if (GR_GL_TEXTURE_EXTERNAL == texture->target()) { - // We don't currently support writing pixels to EXTERNAL textures. - return false; - } - if (GrPixelConfigIsUnorm(texture->config()) && texture->hasBaseLevelBeenBoundToFBO() && - this->glCaps().disallowTexSubImageForUnormConfigTexturesEverBoundToFBO() && - (width < dstSurface->width() || height < dstSurface->height())) { - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - } - } else { - // This subclass only allows writes to textures. If the dst is not a texture we have to draw - // into it. We could use glDrawPixels on GLs that have it, but we don't today. - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - } - - // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target. - if (dstSurface->asRenderTarget() && dstSurface->asRenderTarget()->numColorSamples() > 1) { - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - } - - auto srcAsConfig = GrColorTypeToPixelConfig(srcColorType, srcConfigSRGBEncoded); - SkASSERT(srcAsConfig != kUnknown_GrPixelConfig); - auto dstColorType = GrPixelConfigToColorType(dstSurface->config()); - bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcAsConfig) == dstSurface->config(); - - if (configsAreRBSwaps) { - if (!this->caps()->isConfigTexturable(srcAsConfig)) { - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); - tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); - tempDrawInfo->fWriteColorType = dstColorType; - } else if (this->glCaps().rgba8888PixelsOpsAreSlow() && - kRGBA_8888_GrPixelConfig == srcAsConfig) { - ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); - tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); - tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); - tempDrawInfo->fWriteColorType = dstColorType; - } else if (kGLES_GrGLStandard == this->glStandard() && - this->glCaps().bgraIsInternalFormat()) { - // The internal format and external formats must match texture uploads so we can't - // swizzle while uploading when BGRA is a distinct internal format. - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); - tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); - tempDrawInfo->fWriteColorType = dstColorType; - } - } - - if (!this->glCaps().unpackFlipYSupport() && kBottomLeft_GrSurfaceOrigin == dstOrigin) { - ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); - } - - return true; -} - static bool check_write_and_transfer_input(GrGLTexture* glTex) { if (!glTex) { return false; diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index e827dbc570..06a1dee004 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -231,9 +231,6 @@ private: // variations above, depending on whether the surface is a render target or not. bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig); - bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrColorType, - DrawPreference*, WritePixelTempDrawInfo*) override; - bool onReadPixels(GrSurface*, GrSurfaceOrigin, int left, int top, int width, int height, GrColorType, void* buffer, size_t rowBytes) override; diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index 62064b2b6e..e61b817646 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -71,11 +71,6 @@ private: GrBuffer* onCreateBuffer(size_t sizeInBytes, GrBufferType, GrAccessPattern, const void*) override; - bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin, int width, int height, - GrColorType, DrawPreference*, WritePixelTempDrawInfo*) override { - return true; - } - bool onReadPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height, GrColorType, void* buffer, size_t rowBytes) override { return true; diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index 6b2f3c2933..329103e3a6 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -31,12 +31,6 @@ public: id<MTLDevice> device() const { return fDevice; } - bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, - int height, GrColorType srcColorType, DrawPreference*, - WritePixelTempDrawInfo*) override { - return false; - } - bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect, diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index b9d7ea1f89..59e3e612f8 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -327,54 +327,6 @@ GrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPatter return buff; } -//////////////////////////////////////////////////////////////////////////////// -bool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, - int height, GrColorType srcColorType, - DrawPreference* drawPreference, - WritePixelTempDrawInfo* tempDrawInfo) { - // We don't want to introduce a sRGB conversion if we trigger a draw. - auto srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(dstSurface->config()); - if (*drawPreference != kNoDraw_DrawPreference) { - // We assume the base class has only inserted a draw for sRGB reasons. So the temp surface - // has the config of the original src data. There is no swizzling nor src config spoofing. - SkASSERT(tempDrawInfo->fWriteColorType == srcColorType); - SkASSERT(GrPixelConfigToColorType(tempDrawInfo->fTempSurfaceDesc.fConfig) == srcColorType); - SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA()); - // Don't undo a sRGB conversion introduced by our caller via an intermediate draw. - srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(tempDrawInfo->fTempSurfaceDesc.fConfig); - } - if (GrColorTypeIsAlphaOnly(srcColorType)) { - srcConfigSRGBEncoded = GrSRGBEncoded::kNo; - } - GrRenderTarget* renderTarget = dstSurface->asRenderTarget(); - - if (GrPixelConfigToColorType(dstSurface->config()) == srcColorType) { - // We only support writing pixels to textures. Forcing a draw lets us write to pure RTs. - if (!dstSurface->asTexture()) { - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - } - // If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target. - if (renderTarget && renderTarget->numColorSamples() > 1) { - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - } - return true; - } - - // Any color type change requires a draw - ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); - - auto srcAsConfig = GrColorTypeToPixelConfig(srcColorType, srcConfigSRGBEncoded); - SkASSERT(srcAsConfig != kUnknown_GrPixelConfig); - bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcAsConfig) == dstSurface->config(); - - if (!this->vkCaps().isConfigTexturable(srcAsConfig) && configsAreRBSwaps) { - tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config(); - tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); - tempDrawInfo->fWriteColorType = GrPixelConfigToColorType(dstSurface->config()); - } - return true; -} - bool GrVkGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, int width, int height, GrColorType srcColorType, const GrMipLevel texels[], int mipLevelCount) { diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index ae5447eb9e..01e4ec7f70 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -165,9 +165,6 @@ private: GrBuffer* onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern, const void* data) override; - bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrColorType, - DrawPreference*, WritePixelTempDrawInfo*) override; - bool onReadPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height, GrColorType, void* buffer, size_t rowBytes) override; |