diff options
Diffstat (limited to 'src/gpu')
28 files changed, 799 insertions, 127 deletions
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp index 3835bfaa26..3ec773da5c 100644 --- a/src/gpu/GrBackendTextureImageGenerator.cpp +++ b/src/gpu/GrBackendTextureImageGenerator.cpp @@ -44,8 +44,8 @@ GrBackendTextureImageGenerator::Make(sk_sp<GrTexture> texture, GrSurfaceOrigin o context->contextPriv().getResourceCache()->insertCrossContextGpuResource(texture.get()); GrBackendTexture backendTexture = texture->getBackendTexture(); - if (!context->caps()->validateBackendTexture(backendTexture, colorType, - &backendTexture.fConfig)) { + if (!context->contextPriv().caps()->validateBackendTexture(backendTexture, colorType, + &backendTexture.fConfig)) { return nullptr; } diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h new file mode 100644 index 0000000000..5858afa3c1 --- /dev/null +++ b/src/gpu/GrCaps.h @@ -0,0 +1,349 @@ + +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef GrCaps_DEFINED +#define GrCaps_DEFINED + +#include "../private/GrTypesPriv.h" +#include "GrBlend.h" +#include "GrShaderCaps.h" +#include "SkImageInfo.h" +#include "SkRefCnt.h" +#include "SkString.h" + +class GrBackendFormat; +class GrBackendRenderTarget; +class GrBackendTexture; +struct GrContextOptions; +class GrRenderTargetProxy; +class GrSurface; +class GrSurfaceProxy; +class SkJSONWriter; + +/** + * Represents the capabilities of a GrContext. + */ +class GrCaps : public SkRefCnt { +public: + GrCaps(const GrContextOptions&); + + void dumpJSON(SkJSONWriter*) const; + + const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); } + + bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } + /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. + only for POT textures) */ + bool mipMapSupport() const { return fMipMapSupport; } + + /** + * Skia convention is that a device only has sRGB support if it supports sRGB formats for both + * textures and framebuffers. In addition: + * Decoding to linear of an sRGB texture can be disabled. + */ + bool srgbSupport() const { return fSRGBSupport; } + /** + * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? + */ + bool srgbWriteControl() const { return fSRGBWriteControl; } + bool srgbDecodeDisableSupport() const { return fSRGBDecodeDisableSupport; } + bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } + bool gpuTracingSupport() const { return fGpuTracingSupport; } + bool oversizedStencilSupport() const { return fOversizedStencilSupport; } + bool textureBarrierSupport() const { return fTextureBarrierSupport; } + bool sampleLocationsSupport() const { return fSampleLocationsSupport; } + bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } + bool instanceAttribSupport() const { return fInstanceAttribSupport; } + bool usesMixedSamples() const { return fUsesMixedSamples; } + + // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some + // systems. This cap is only set if primitive restart will improve performance. + bool usePrimitiveRestart() const { return fUsePrimitiveRestart; } + + bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; } + + // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to + // initialize each tile with a constant value rather than loading each pixel from memory. + bool preferFullscreenClears() const { return fPreferFullscreenClears; } + + bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } + + bool blacklistCoverageCounting() const { return fBlacklistCoverageCounting; } + + bool avoidStencilBuffers() const { return fAvoidStencilBuffers; } + + /** + * Indicates the capabilities of the fixed function blend unit. + */ + enum BlendEquationSupport { + kBasic_BlendEquationSupport, //<! Support to select the operator that + // combines src and dst terms. + kAdvanced_BlendEquationSupport, //<! Additional fixed function support for specific + // SVG/PDF blend modes. Requires blend barriers. + kAdvancedCoherent_BlendEquationSupport, //<! Advanced blend equation support that does not + // require blend barriers, and permits overlap. + + kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport + }; + + BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } + + bool advancedBlendEquationSupport() const { + return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; + } + + bool advancedCoherentBlendEquationSupport() const { + return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; + } + + bool canUseAdvancedBlendEquation(GrBlendEquation equation) const { + SkASSERT(GrBlendEquationIsAdvanced(equation)); + return SkToBool(fAdvBlendEqBlacklist & (1 << equation)); + } + + /** + * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and + * textures allows partial mappings or full mappings. + */ + enum MapFlags { + kNone_MapFlags = 0x0, //<! Cannot map the resource. + + kCanMap_MapFlag = 0x1, //<! The resource can be mapped. Must be set for any of + // the other flags to have meaning. + kSubset_MapFlag = 0x2, //<! The resource can be partially mapped. + }; + + uint32_t mapBufferFlags() const { return fMapBufferFlags; } + + // Scratch textures not being reused means that those scratch textures + // that we upload to (i.e., don't have a render target) will not be + // recycled in the texture cache. This is to prevent ghosting by drivers + // (in particular for deferred architectures). + bool reuseScratchTextures() const { return fReuseScratchTextures; } + bool reuseScratchBuffers() const { return fReuseScratchBuffers; } + + /// maximum number of attribute values per vertex + int maxVertexAttributes() const { return fMaxVertexAttributes; } + + int maxRenderTargetSize() const { return fMaxRenderTargetSize; } + + /** This is the largest render target size that can be used without incurring extra perfomance + cost. It is usually the max RT size, unless larger render targets are known to be slower. */ + int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; } + + int maxTextureSize() const { return fMaxTextureSize; } + + /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps. + It is usually the max texture size, unless we're overriding it for testing. */ + int maxTileSize() const { + SkASSERT(fMaxTileSize <= fMaxTextureSize); + return fMaxTileSize; + } + + int maxRasterSamples() const { return fMaxRasterSamples; } + + int maxWindowRectangles() const { return fMaxWindowRectangles; } + + // Returns whether mixed samples is supported for the given backend render target. + bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const { + return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt); + } + + // A tuned, platform-specific value for the maximum number of analytic fragment processors we + // should use to implement a clip, before falling back on a mask. + int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; } + + virtual bool isConfigTexturable(GrPixelConfig) const = 0; + + // Returns whether a texture of the given config can be copied to a texture of the same config. + virtual bool isConfigCopyable(GrPixelConfig) const = 0; + + // Returns the maximum supported sample count for a config. 0 means the config is not renderable + // 1 means the config is renderable but doesn't support MSAA. + virtual int maxRenderTargetSampleCount(GrPixelConfig) const = 0; + + bool isConfigRenderable(GrPixelConfig config) const { + return this->maxRenderTargetSampleCount(config) > 0; + } + + // TODO: Remove this after Flutter updated to no longer use it. + bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const { + return this->maxRenderTargetSampleCount(config) > (withMSAA ? 1 : 0); + } + + // Find a sample count greater than or equal to the requested count which is supported for a + // color buffer of the given config or 0 if no such sample count is supported. If the requested + // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0. + // For historical reasons requestedCount==0 is handled identically to requestedCount==1. + virtual int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const = 0; + // TODO: Remove. Legacy name used by Chrome. + int getSampleCount(int requestedCount, GrPixelConfig config) const { + return this->getRenderTargetSampleCount(requestedCount, config); + } + + /** + * Backends may have restrictions on what types of surfaces support GrGpu::writePixels(). + * If this returns false then the caller should implement a fallback where a temporary texture + * is created, pixels are written to it, and then that is copied or drawn into the the surface. + */ + virtual bool surfaceSupportsWritePixels(const GrSurface*) const = 0; + + /** + * Backends may have restrictions on what types of surfaces support GrGpu::readPixels(). + * If this returns false then the caller should implement a fallback where a temporary texture + * is created, the surface is drawn or copied into the temporary, and pixels are read from the + * temporary. + */ + virtual bool surfaceSupportsReadPixels(const GrSurface*) const = 0; + + /** + * Given a dst pixel config and a src color type what color type must the caller coax the + * the data into in order to use GrGpu::writePixels(). + */ + virtual GrColorType supportedWritePixelsColorType(GrPixelConfig config, + GrColorType /*srcColorType*/) const { + return GrPixelConfigToColorType(config); + } + + /** + * Given a src pixel config and a dst color type what color type must the caller read to using + * GrGpu::readPixels() and then coax into dstColorType. + */ + virtual GrColorType supportedReadPixelsColorType(GrPixelConfig config, + GrColorType /*dstColorType*/) const { + return GrPixelConfigToColorType(config); + } + + bool suppressPrints() const { return fSuppressPrints; } + + size_t bufferMapThreshold() const { + SkASSERT(fBufferMapThreshold >= 0); + return fBufferMapThreshold; + } + + /** True in environments that will issue errors if memory uploaded to buffers + is not initialized (even if not read by draw calls). */ + bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } + + bool wireframeMode() const { return fWireframeMode; } + + bool sampleShadingSupport() const { return fSampleShadingSupport; } + + bool fenceSyncSupport() const { return fFenceSyncSupport; } + bool crossContextTextureSupport() const { return fCrossContextTextureSupport; } + + /** + * Returns whether or not we will be able to do a copy given the passed in params + */ + virtual bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, + const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0; + + /** + * This is can be called before allocating a texture to be a dst for copySurface. This is only + * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It + * will populate config and flags fields of the desc such that copySurface can efficiently + * succeed as well as the proxy origin. rectsMustMatch will be set to true if the copy operation + * must ensure that the src and dest rects are identical. disallowSubrect will be set to true if + * copy rect must equal src's bounds. + */ + virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, + GrSurfaceOrigin* origin, bool* rectsMustMatch, + bool* disallowSubrect) const = 0; + + bool validateSurfaceDesc(const GrSurfaceDesc&, GrMipMapped) const; + + /** + * Returns true if the GrBackendTexture can be used with the supplied SkColorType. If it is + * compatible, the passed in GrPixelConfig will be set to a config that matches the backend + * format and requested SkColorType. + */ + virtual bool validateBackendTexture(const GrBackendTexture& tex, SkColorType ct, + GrPixelConfig*) const = 0; + virtual bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType, + GrPixelConfig*) const = 0; + + // TODO: replace validateBackendTexture and validateBackendRenderTarget with calls to + // getConfigFromBackendFormat? + // TODO: it seems like we could pass the full SkImageInfo and validate its colorSpace too + virtual bool getConfigFromBackendFormat(const GrBackendFormat& format, SkColorType ct, + GrPixelConfig*) const = 0; + +protected: + /** Subclasses must call this at the end of their constructors in order to apply caps + overrides requested by the client. Note that overrides will only reduce the caps never + expand them. */ + void applyOptionsOverrides(const GrContextOptions& options); + + sk_sp<GrShaderCaps> fShaderCaps; + + bool fNPOTTextureTileSupport : 1; + bool fMipMapSupport : 1; + bool fSRGBSupport : 1; + bool fSRGBWriteControl : 1; + bool fSRGBDecodeDisableSupport : 1; + bool fDiscardRenderTargetSupport : 1; + bool fReuseScratchTextures : 1; + bool fReuseScratchBuffers : 1; + bool fGpuTracingSupport : 1; + bool fOversizedStencilSupport : 1; + bool fTextureBarrierSupport : 1; + bool fSampleLocationsSupport : 1; + bool fMultisampleDisableSupport : 1; + bool fInstanceAttribSupport : 1; + bool fUsesMixedSamples : 1; + bool fUsePrimitiveRestart : 1; + bool fPreferClientSideDynamicBuffers : 1; + bool fPreferFullscreenClears : 1; + bool fMustClearUploadedBufferData : 1; + + // Driver workaround + bool fBlacklistCoverageCounting : 1; + bool fAvoidStencilBuffers : 1; + + // ANGLE performance workaround + bool fPreferVRAMUseOverFlushes : 1; + + bool fSampleShadingSupport : 1; + // TODO: this may need to be an enum to support different fence types + bool fFenceSyncSupport : 1; + + // Vulkan doesn't support this (yet) and some drivers have issues, too + bool fCrossContextTextureSupport : 1; + + BlendEquationSupport fBlendEquationSupport; + uint32_t fAdvBlendEqBlacklist; + GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); + + uint32_t fMapBufferFlags; + int fBufferMapThreshold; + + int fMaxRenderTargetSize; + int fMaxPreferredRenderTargetSize; + int fMaxVertexAttributes; + int fMaxTextureSize; + int fMaxTileSize; + int fMaxRasterSamples; + int fMaxWindowRectangles; + int fMaxClipAnalyticFPs; + +private: + virtual void onApplyOptionsOverrides(const GrContextOptions&) {} + virtual void onDumpJSON(SkJSONWriter*) const {} + + // Backends should implement this if they have any extra requirements for use of window + // rectangles for a specific GrBackendRenderTarget outside of basic support. + virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const { + return true; + } + + bool fSuppressPrints : 1; + bool fWireframeMode : 1; + + typedef SkRefCnt INHERITED; +}; + +#endif diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index f5c08f07eb..92a6d04340 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -117,14 +117,14 @@ bool GrClipStackClip::PathNeedsSWRenderer(GrContext* context, GrShape shape(path, GrStyle::SimpleFill()); GrPathRenderer::CanDrawPathArgs canDrawArgs; - canDrawArgs.fCaps = context->caps(); + canDrawArgs.fCaps = context->contextPriv().caps(); canDrawArgs.fClipConservativeBounds = &scissorRect; canDrawArgs.fViewMatrix = &viewMatrix; canDrawArgs.fShape = &shape; canDrawArgs.fAAType = GrChooseAAType(GrAA(element->isAA()), renderTargetContext->fsaaType(), GrAllowMixedSamples::kYes, - *context->caps()); + *context->contextPriv().caps()); canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings; // the 'false' parameter disallows use of the SW path renderer @@ -151,8 +151,9 @@ bool GrClipStackClip::UseSWOnlyPath(GrContext* context, // of whether it would invoke the GrSoftwarePathRenderer. // If we're avoiding stencils, always use SW: - if (context->caps()->avoidStencilBuffers()) + if (context->contextPriv().caps()->avoidStencilBuffers()) { return true; + } // Set the matrix so that rendered clip elements are transformed to mask space from clip // space. @@ -191,9 +192,9 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar } GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); - const auto* caps = context->caps()->shaderCaps(); + const auto* caps = context->contextPriv().caps()->shaderCaps(); int maxWindowRectangles = renderTargetContext->priv().maxWindowRectangles(); - int maxAnalyticFPs = context->caps()->maxClipAnalyticFPs(); + int maxAnalyticFPs = context->contextPriv().caps()->maxClipAnalyticFPs(); if (GrFSAAType::kNone != renderTargetContext->fsaaType()) { // With mixed samples (non-msaa color buffer), any coverage info is lost from color once it // hits the color buffer anyway, so we may as well use coverage AA if nothing else in the @@ -201,7 +202,8 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar if (renderTargetContext->numColorSamples() > 1 || useHWAA || hasUserStencilSettings) { maxAnalyticFPs = 0; } - SkASSERT(!context->caps()->avoidStencilBuffers()); // We disable MSAA when avoiding stencil. + // We disable MSAA when avoiding stencil. + SkASSERT(!context->contextPriv().caps()->avoidStencilBuffers()); } auto* ccpr = context->contextPriv().drawingManager()->getCoverageCountingPathRenderer(); @@ -253,7 +255,7 @@ bool GrClipStackClip::applyClipMask(GrContext* context, GrRenderTargetContext* r // If the stencil buffer is multisampled we can use it to do everything. if ((GrFSAAType::kNone == renderTargetContext->fsaaType() && reducedClip.maskRequiresAA()) || - context->caps()->avoidStencilBuffers()) { + context->contextPriv().caps()->avoidStencilBuffers()) { sk_sp<GrTextureProxy> result; if (UseSWOnlyPath(context, hasUserStencilSettings, renderTargetContext, reducedClip)) { // The clip geometry is complex enough that it will be more efficient to create it @@ -272,7 +274,7 @@ bool GrClipStackClip::applyClipMask(GrContext* context, GrRenderTargetContext* r // If alpha or software clip mask creation fails, fall through to the stencil code paths, // unless stencils are disallowed. - if (context->caps()->avoidStencilBuffers()) { + if (context->contextPriv().caps()->avoidStencilBuffers()) { SkDebugf("WARNING: Clip mask requires stencil, but stencil unavailable. " "Clip will be ignored.\n"); return false; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 499c71107c..3bb5b3a1fb 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -163,6 +163,16 @@ GrContext::~GrContext() { delete fGlyphCache; } +////////////////////////////////////////////////////////////////////////////// + +GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID, + GrBackend backend, + const GrContextOptions& options) + : fCaps(std::move(caps)) + , fContextUniqueID(uniqueID) + , fBackend(backend) + , fOptions(options) {} + sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() { return fThreadSafeProxy; } @@ -314,18 +324,18 @@ size_t GrContext::getResourceCachePurgeableBytes() const { //////////////////////////////////////////////////////////////////////////////// -int GrContext::maxTextureSize() const { return this->caps()->maxTextureSize(); } +int GrContext::maxTextureSize() const { return fCaps->maxTextureSize(); } -int GrContext::maxRenderTargetSize() const { return this->caps()->maxRenderTargetSize(); } +int GrContext::maxRenderTargetSize() const { return fCaps->maxRenderTargetSize(); } bool GrContext::colorTypeSupportedAsImage(SkColorType colorType) const { - GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps()); - return this->caps()->isConfigTexturable(config); + GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *fCaps); + return fCaps->isConfigTexturable(config); } int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const { - GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps()); - return this->caps()->maxRenderTargetSampleCount(config); + GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *fCaps); + return fCaps->maxRenderTargetSampleCount(config); } //////////////////////////////////////////////////////////////////////////////// @@ -574,7 +584,7 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst, int left, int top, GrGpu::WritePixelTempDrawInfo tempDrawInfo; GrSRGBConversion srgbConversion = determine_write_pixels_srgb_conversion( srcColorType, srcColorSpace, GrPixelConfigIsSRGBEncoded(dstProxy->config()), - dst->colorSpaceInfo().colorSpace(), *fContext->caps()); + dst->colorSpaceInfo().colorSpace(), *fContext->contextPriv().caps()); if (!fContext->fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(), width, height, srcColorType, srgbConversion, &drawPreference, &tempDrawInfo)) { @@ -743,7 +753,7 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src, int left, int top, GrGpu::ReadPixelTempDrawInfo tempDrawInfo; GrSRGBConversion srgbConversion = determine_read_pixels_srgb_conversion( GrPixelConfigIsSRGBEncoded(srcProxy->config()), src->colorSpaceInfo().colorSpace(), - dstColorType, dstColorSpace, *fContext->caps()); + dstColorType, dstColorSpace, *fContext->contextPriv().caps()); if (!fContext->fGpu->getReadPixelsInfo(srcSurface, srcProxy->origin(), width, height, rowBytes, dstColorType, srgbConversion, &drawPreference, @@ -895,10 +905,11 @@ bool GrContextPriv::writeSurfacePixels2(GrSurfaceContext* dst, int left, int top (dstProxy->config() == kRGBA_8888_GrPixelConfig || dstProxy->config() == kBGRA_8888_GrPixelConfig) && !(pixelOpsFlags & kDontFlush_PixelOpsFlag) && - fContext->caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) && + fContext->contextPriv().caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) && fContext->validPMUPMConversionExists(); - if (!fContext->caps()->surfaceSupportsWritePixels(dstSurface) || canvas2DFastPath) { + if (!fContext->contextPriv().caps()->surfaceSupportsWritePixels(dstSurface) || + canvas2DFastPath) { // We don't expect callers that are skipping flushes to require an intermediate draw. SkASSERT(!(pixelOpsFlags & kDontFlush_PixelOpsFlag)); if (pixelOpsFlags & kDontFlush_PixelOpsFlag) { @@ -957,8 +968,8 @@ bool GrContextPriv::writeSurfacePixels2(GrSurfaceContext* dst, int left, int top return false; } - GrColorType allowedColorType = - fContext->caps()->supportedWritePixelsColorType(dstProxy->config(), srcColorType); + GrColorType allowedColorType = fContext->contextPriv().caps()->supportedWritePixelsColorType( + dstProxy->config(), srcColorType); convert = convert || (srcColorType != allowedColorType); if (!dst->colorSpaceInfo().colorSpace()) { @@ -1071,10 +1082,11 @@ bool GrContextPriv::readSurfacePixels2(GrSurfaceContext* src, int left, int top, SkToBool(srcProxy->asTextureProxy()) && (srcProxy->config() == kRGBA_8888_GrPixelConfig || srcProxy->config() == kBGRA_8888_GrPixelConfig) && - fContext->caps()->isConfigRenderable(kRGBA_8888_GrPixelConfig) && + fContext->contextPriv().caps()->isConfigRenderable(kRGBA_8888_GrPixelConfig) && fContext->validPMUPMConversionExists(); - if (!fContext->caps()->surfaceSupportsReadPixels(srcSurface) || canvas2DFastPath) { + if (!fContext->contextPriv().caps()->surfaceSupportsReadPixels(srcSurface) || + canvas2DFastPath) { GrSurfaceDesc desc; desc.fFlags = canvas2DFastPath ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; desc.fConfig = canvas2DFastPath ? kRGBA_8888_GrPixelConfig : srcProxy->config(); @@ -1132,8 +1144,8 @@ bool GrContextPriv::readSurfacePixels2(GrSurfaceContext* src, int left, int top, top = srcSurface->height() - top - height; } - GrColorType allowedColorType = - fContext->caps()->supportedReadPixelsColorType(srcProxy->config(), dstColorType); + GrColorType allowedColorType = fContext->contextPriv().caps()->supportedReadPixelsColorType( + srcProxy->config(), dstColorType); convert = convert || (dstColorType != allowedColorType); if (!src->colorSpaceInfo().colorSpace()) { @@ -1392,7 +1404,7 @@ sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithF const SkSurfaceProps* surfaceProps, SkBudgeted budgeted) { SkASSERT(sampleCnt > 0); - if (0 == fContext->caps()->getRenderTargetSampleCount(sampleCnt, config)) { + if (0 == fContext->contextPriv().caps()->getRenderTargetSampleCount(sampleCnt, config)) { config = GrPixelConfigFallback(config); } diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 61ff3c1e34..7e6ecb8310 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -30,6 +30,8 @@ public: */ static sk_sp<GrContext> MakeDDL(const sk_sp<GrContextThreadSafeProxy>&); + const GrCaps* caps() const { return fContext->fCaps.get(); } + GrDrawingManager* drawingManager() { return fContext->fDrawingManager.get(); } sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy>, diff --git a/src/gpu/GrDDLContext.cpp b/src/gpu/GrDDLContext.cpp index 5ed65ea5f0..1ae640c3e3 100644 --- a/src/gpu/GrDDLContext.cpp +++ b/src/gpu/GrDDLContext.cpp @@ -6,6 +6,7 @@ */ #include "GrContext.h" +#include "GrCaps.h" #include "GrContextPriv.h" #include "GrContextThreadSafeProxyPriv.h" diff --git a/src/gpu/GrDrawOpTest.cpp b/src/gpu/GrDrawOpTest.cpp index 7aba424b3d..d14e5b53d7 100644 --- a/src/gpu/GrDrawOpTest.cpp +++ b/src/gpu/GrDrawOpTest.cpp @@ -8,6 +8,7 @@ #include "GrDrawOpTest.h" #include "GrCaps.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "GrUserStencilSettings.h" #include "SkRandom.h" #include "SkTypes.h" @@ -15,7 +16,7 @@ #if GR_TEST_UTILS const GrUserStencilSettings* GrGetRandomStencil(SkRandom* random, GrContext* context) { - if (context->caps()->avoidStencilBuffers()) { + if (context->contextPriv().caps()->avoidStencilBuffers()) { return &GrUserStencilSettings::kUnused; } static constexpr GrUserStencilSettings kReads( diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index ffacf55cba..de414ae545 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -6,7 +6,6 @@ */ #include "GrDrawingManager.h" - #include "GrBackendSemaphore.h" #include "GrContext.h" #include "GrContextPriv.h" @@ -23,11 +22,9 @@ #include "GrTextureOpList.h" #include "GrTextureProxy.h" #include "GrTextureProxyPriv.h" - #include "SkDeferredDisplayList.h" #include "SkSurface_Gpu.h" #include "SkTTopoSort.h" - #include "GrTracing.h" #include "text/GrAtlasTextContext.h" @@ -65,7 +62,7 @@ GrDrawingManager::GrDrawingManager(GrContext* context, void GrDrawingManager::cleanup() { for (int i = 0; i < fOpLists.count(); ++i) { // no opList should receive a new command after this - fOpLists[i]->makeClosed(*fContext->caps()); + fOpLists[i]->makeClosed(*fContext->contextPriv().caps()); // We shouldn't need to do this, but it turns out some clients still hold onto opLists // after a cleanup. @@ -130,7 +127,7 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed // but need to be flushed anyway. Closing such GrOpLists here will mean new // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again. - fOpLists[i]->makeClosed(*fContext->caps()); + fOpLists[i]->makeClosed(*fContext->contextPriv().caps()); } #ifdef SK_DEBUG @@ -186,7 +183,7 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, SkASSERT(GrSurfaceProxy::LazyState::kNot == p->lazyInstantiationState()); }); #endif - onFlushOpList->makeClosed(*fContext->caps()); + onFlushOpList->makeClosed(*fContext->contextPriv().caps()); onFlushOpList->prepare(&flushState); fOnFlushCBOpLists.push_back(std::move(onFlushOpList)); } @@ -380,7 +377,7 @@ void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlush void GrDrawingManager::moveOpListsToDDL(SkDeferredDisplayList* ddl) { for (int i = 0; i < fOpLists.count(); ++i) { // no opList should receive a new command after this - fOpLists[i]->makeClosed(*fContext->caps()); + fOpLists[i]->makeClosed(*fContext->contextPriv().caps()); } ddl->fOpLists = std::move(fOpLists); @@ -402,7 +399,7 @@ sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* r // so ops that (in the single opList world) would've just glommed onto the end of the single // opList but referred to a far earlier RT need to appear in their own opList. if (!fOpLists.empty()) { - fOpLists.back()->makeClosed(*fContext->caps()); + fOpLists.back()->makeClosed(*fContext->contextPriv().caps()); } auto resourceProvider = fContext->contextPriv().resourceProvider(); @@ -427,7 +424,7 @@ sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textur // so ops that (in the single opList world) would've just glommed onto the end of the single // opList but referred to a far earlier RT need to appear in their own opList. if (!fOpLists.empty()) { - fOpLists.back()->makeClosed(*fContext->caps()); + fOpLists.back()->makeClosed(*fContext->contextPriv().caps()); } sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->contextPriv().resourceProvider(), @@ -502,7 +499,7 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext( // SkSurface catches bad color space usage at creation. This check handles anything that slips // by, including internal usage. - if (!SkSurface_Gpu::Valid(fContext->caps(), sProxy->config(), colorSpace.get())) { + if (!SkSurface_Gpu::Valid(fContext->contextPriv().caps(), sProxy->config(), colorSpace.get())) { SkDEBUGFAIL("Invalid config and colorspace combination"); return nullptr; } @@ -525,7 +522,7 @@ sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProx // SkSurface catches bad color space usage at creation. This check handles anything that slips // by, including internal usage. - if (!SkSurface_Gpu::Valid(fContext->caps(), sProxy->config(), colorSpace.get())) { + if (!SkSurface_Gpu::Valid(fContext->contextPriv().caps(), sProxy->config(), colorSpace.get())) { SkDEBUGFAIL("Invalid config and colorspace combination"); return nullptr; } diff --git a/src/gpu/GrImageTextureMaker.cpp b/src/gpu/GrImageTextureMaker.cpp index 5bf81d2d8f..920415f55c 100644 --- a/src/gpu/GrImageTextureMaker.cpp +++ b/src/gpu/GrImageTextureMaker.cpp @@ -6,12 +6,12 @@ */ #include "GrImageTextureMaker.h" - #include "GrContext.h" +#include "GrContextPriv.h" #include "GrGpuResourcePriv.h" #include "SkGr.h" -#include "SkImage_Base.h" #include "SkImageCacherator.h" +#include "SkImage_Base.h" #include "SkPixelRef.h" GrImageTextureMaker::GrImageTextureMaker(GrContext* context, const SkImage* client, @@ -36,7 +36,7 @@ void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* pa SkColorSpace* dstColorSpace) { if (fOriginalKey.isValid() && SkImage::kAllow_CachingHint == fCachingHint) { SkImageCacherator::CachedFormat cacheFormat = - fCacher->chooseCacheFormat(dstColorSpace, this->context()->caps()); + fCacher->chooseCacheFormat(dstColorSpace, this->context()->contextPriv().caps()); GrUniqueKey cacheKey; fCacher->makeCacheKeyFromOrigKey(fOriginalKey, cacheFormat, &cacheKey); MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey); diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp index d892dee102..9e2e1fee4a 100644 --- a/src/gpu/GrOnFlushResourceProvider.cpp +++ b/src/gpu/GrOnFlushResourceProvider.cpp @@ -115,5 +115,5 @@ sk_sp<const GrBuffer> GrOnFlushResourceProvider::findOrMakeStaticBuffer(GrBuffer } const GrCaps* GrOnFlushResourceProvider::caps() const { - return fDrawingMgr->getContext()->caps(); + return fDrawingMgr->getContext()->contextPriv().caps(); } diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index c5a1f63fa1..39208bc635 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -9,18 +9,17 @@ #define GrPathRenderer_DEFINED #include "GrCaps.h" -#include "GrRenderTargetContext.h" +#include "GrContextPriv.h" #include "GrPaint.h" +#include "GrRenderTargetContext.h" #include "GrShape.h" #include "GrUserStencilSettings.h" - #include "SkDrawProcs.h" #include "SkTArray.h" class SkPath; class GrFixedClip; class GrHardClip; -struct GrPoint; /** * Base class for drawing paths into a GrOpList. @@ -138,7 +137,7 @@ public: SkDEBUGCODE(args.validate();) #ifdef SK_DEBUG CanDrawPathArgs canArgs; - canArgs.fCaps = args.fContext->caps(); + canArgs.fCaps = args.fContext->contextPriv().caps(); canArgs.fClipConservativeBounds = args.fClipConservativeBounds; canArgs.fViewMatrix = args.fViewMatrix; canArgs.fShape = args.fShape; diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index bc776342ae..4dc814e59a 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -7,15 +7,12 @@ #include "GrPathRendererChain.h" - #include "GrCaps.h" #include "GrShaderCaps.h" #include "GrContext.h" #include "GrContextPriv.h" #include "GrGpu.h" - #include "ccpr/GrCoverageCountingPathRenderer.h" - #include "ops/GrAAConvexPathRenderer.h" #include "ops/GrAAHairLinePathRenderer.h" #include "ops/GrAALinearizingConvexPathRenderer.h" @@ -26,7 +23,7 @@ #include "ops/GrTessellatingPathRenderer.h" GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& options) { - const GrCaps& caps = *context->caps(); + const GrCaps& caps = *context->contextPriv().caps(); if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) { fChain.push_back(sk_make_sp<GrDashLinePathRenderer>()); } @@ -43,8 +40,8 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti if (options.fGpuPathRenderers & GpuPathRenderers::kCoverageCounting) { bool drawCachablePaths = !options.fAllowPathMaskCaching; - if (auto ccpr = GrCoverageCountingPathRenderer::CreateIfSupported(*context->caps(), - drawCachablePaths)) { + if (auto ccpr = + GrCoverageCountingPathRenderer::CreateIfSupported(caps, drawCachablePaths)) { fCoverageCountingPathRenderer = ccpr.get(); context->contextPriv().addOnFlushCallbackObject(fCoverageCountingPathRenderer); fChain.push_back(std::move(ccpr)); diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 2b02b8df20..561fd4fee8 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -25,9 +25,7 @@ GrProxyProvider* GrProcessorTestData::proxyProvider() { return fContext->contextPriv().proxyProvider(); } -const GrCaps* GrProcessorTestData::caps() { - return fContext->caps(); -} +const GrCaps* GrProcessorTestData::caps() { return fContext->contextPriv().caps(); } #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS class GrFragmentProcessor; diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp index 1c5150c679..e6cd6b36fe 100644 --- a/src/gpu/GrReducedClip.cpp +++ b/src/gpu/GrReducedClip.cpp @@ -847,7 +847,7 @@ bool GrReducedClip::drawStencilClipMask(GrContext* context, GrShape shape(clipPath, GrStyle::SimpleFill()); GrPathRenderer::CanDrawPathArgs canDrawArgs; - canDrawArgs.fCaps = context->caps(); + canDrawArgs.fCaps = context->contextPriv().caps(); canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect(); canDrawArgs.fViewMatrix = &SkMatrix::I(); canDrawArgs.fShape = &shape; diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 6d8f6cd430..c447a5c366 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -340,7 +340,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip, if (!clip.hasWindowRectangles()) { isFull = !clip.scissorEnabled() || (CanClearFullscreen::kYes == canClearFullscreen && - fContext->caps()->preferFullscreenClears()) || + this->caps()->preferFullscreenClears()) || clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height())); } @@ -589,7 +589,7 @@ void GrRenderTargetContext::drawRect(const GrClip& clip, int GrRenderTargetContextPriv::maxWindowRectangles() const { return fRenderTargetContext->fRenderTargetProxy->maxWindowRectangles( - *fRenderTargetContext->fContext->caps()); + *fRenderTargetContext->caps()); } void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) { @@ -917,7 +917,7 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); if (GrAAType::kCoverage == aaType) { - const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); + const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeRRectOp(std::move(paint), viewMatrix, rrect, @@ -1306,7 +1306,7 @@ void GrRenderTargetContext::drawOval(const GrClip& clip, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); if (GrAAType::kCoverage == aaType) { - const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); + const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); if (auto op = GrOvalOpFactory::MakeOvalOp(std::move(paint), viewMatrix, oval, style, shaderCaps)) { this->addDrawOp(clip, std::move(op)); @@ -1337,7 +1337,7 @@ void GrRenderTargetContext::drawArc(const GrClip& clip, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); if (GrAAType::kCoverage == aaType) { - const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); + const GrShaderCaps* shaderCaps = this->caps()->shaderCaps(); std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeArcOp(std::move(paint), viewMatrix, oval, @@ -1563,7 +1563,7 @@ bool GrRenderTargetContextPriv::drawAndStencilPath(const GrHardClip& clip, GrShape shape(path, GrStyle::SimpleFill()); GrPathRenderer::CanDrawPathArgs canDrawArgs; - canDrawArgs.fCaps = fRenderTargetContext->drawingManager()->getContext()->caps(); + canDrawArgs.fCaps = fRenderTargetContext->caps(); canDrawArgs.fViewMatrix = &viewMatrix; canDrawArgs.fShape = &shape; canDrawArgs.fClipConservativeBounds = &clipConservativeBounds; @@ -1627,7 +1627,7 @@ void GrRenderTargetContext::drawShapeUsingPathRenderer(const GrClip& clip, : GrAllowMixedSamples::kYes; GrAAType aaType = this->chooseAAType(aa, allowMixedSamples); GrPathRenderer::CanDrawPathArgs canDrawArgs; - canDrawArgs.fCaps = this->drawingManager()->getContext()->caps(); + canDrawArgs.fCaps = this->caps(); canDrawArgs.fViewMatrix = &viewMatrix; canDrawArgs.fShape = &originalShape; canDrawArgs.fClipConservativeBounds = &clipConservativeBounds; diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 5865da98a5..8d677ae091 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -333,7 +333,7 @@ public: void insertEventMarker(const SkString&); GrFSAAType fsaaType() const { return fRenderTargetProxy->fsaaType(); } - const GrCaps* caps() const { return fContext->caps(); } + const GrCaps* caps() const { return fContext->contextPriv().caps(); } int width() const { return fRenderTargetProxy->width(); } int height() const { return fRenderTargetProxy->height(); } int numColorSamples() const { return fRenderTargetProxy->numColorSamples(); } diff --git a/src/gpu/GrShaderCaps.h b/src/gpu/GrShaderCaps.h new file mode 100644 index 0000000000..2f2d27708a --- /dev/null +++ b/src/gpu/GrShaderCaps.h @@ -0,0 +1,315 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrShaderCaps_DEFINED +#define GrShaderCaps_DEFINED + +#include "../private/GrGLSL.h" +#include "../private/GrSwizzle.h" + +namespace SkSL { +class ShaderCapsFactory; +} + +struct GrContextOptions; +class SkJSONWriter; + +class GrShaderCaps : public SkRefCnt { +public: + /** + * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires + * special layout qualifiers in the fragment shader. + */ + enum AdvBlendEqInteraction { + kNotSupported_AdvBlendEqInteraction, //<! No _blend_equation_advanced extension + kAutomatic_AdvBlendEqInteraction, //<! No interaction required + kGeneralEnable_AdvBlendEqInteraction, //<! layout(blend_support_all_equations) out + kSpecificEnables_AdvBlendEqInteraction, //<! Specific layout qualifiers per equation + + kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction + }; + + GrShaderCaps(const GrContextOptions&); + + void dumpJSON(SkJSONWriter*) const; + + bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; } + bool geometryShaderSupport() const { return fGeometryShaderSupport; } + bool gsInvocationsSupport() const { return fGSInvocationsSupport; } + bool pathRenderingSupport() const { return fPathRenderingSupport; } + bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; } + bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; } + bool integerSupport() const { return fIntegerSupport; } + bool texelBufferSupport() const { return fTexelBufferSupport; } + int imageLoadStoreSupport() const { return fImageLoadStoreSupport; } + + /** + * Some helper functions for encapsulating various extensions to read FB Buffer on openglES + * + * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect + */ + bool fbFetchSupport() const { return fFBFetchSupport; } + + bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; } + + const char* versionDeclString() const { return fVersionDeclString; } + + const char* fbFetchColorName() const { return fFBFetchColorName; } + + const char* fbFetchExtensionString() const { return fFBFetchExtensionString; } + + bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; } + + bool flatInterpolationSupport() const { return fFlatInterpolationSupport; } + + bool preferFlatInterpolation() const { return fPreferFlatInterpolation; } + + bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; } + + bool externalTextureSupport() const { return fExternalTextureSupport; } + + bool texelFetchSupport() const { return fTexelFetchSupport; } + + bool vertexIDSupport() const { return fVertexIDSupport; } + + // frexp, ldexp, etc. + bool fpManipulationSupport() const { return fFPManipulationSupport; } + + bool floatIs32Bits() const { return fFloatIs32Bits; } + + bool halfIs32Bits() const { return fHalfIs32Bits; } + + AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; } + + bool mustEnableAdvBlendEqs() const { + return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction; + } + + bool mustEnableSpecificAdvBlendEqs() const { + return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction; + } + + bool mustDeclareFragmentShaderOutput() const { return fGLSLGeneration > k110_GrGLSLGeneration; } + + bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; } + + // Returns whether we can use the glsl function any() in our shader code. + bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; } + + bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; } + + bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; } + + bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; } + + // Returns whether a device incorrectly implements atan(y,x) as atan(y/x) + bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; } + + // If this returns true some operation (could be a no op) must be called between floor and abs + // to make sure the driver compiler doesn't inline them together which can cause a driver bug in + // the shader. + bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; } + + // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord + bool canUseFragCoord() const { return fCanUseFragCoord; } + + // If true interpolated vertex shader outputs are inaccurate. + bool interpolantsAreInaccurate() const { return fInterpolantsAreInaccurate; } + + // If true, short ints can't represent every integer in the 16-bit two's complement range as + // required by the spec. SKSL will always emit full ints. + bool incompleteShortIntPrecision() const { return fIncompleteShortIntPrecision; } + + bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; } + + bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; } + + // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain + // constructs. See detailed comments in GrGLCaps.cpp. + bool mustGuardDivisionEvenAfterExplicitZeroCheck() const { + return fMustGuardDivisionEvenAfterExplicitZeroCheck; + } + + // Returns the string of an extension that must be enabled in the shader to support + // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling + // this function, the caller should check that shaderDerivativeSupport exists. + const char* shaderDerivativeExtensionString() const { + SkASSERT(this->shaderDerivativeSupport()); + return fShaderDerivativeExtensionString; + } + + // Returns the string of an extension that must be enabled in the shader to support geometry + // shaders. If nullptr is returned then no extension needs to be enabled. Before calling this + // function, the caller must verify that geometryShaderSupport exists. + const char* geometryShaderExtensionString() const { + SkASSERT(this->geometryShaderSupport()); + return fGeometryShaderExtensionString; + } + + // Returns the string of an extension that must be enabled in the shader to support + // geometry shader invocations. If nullptr is returned then no extension needs to be enabled. + // Before calling this function, the caller must verify that gsInvocationsSupport exists. + const char* gsInvocationsExtensionString() const { + SkASSERT(this->gsInvocationsSupport()); + return fGSInvocationsExtensionString; + } + + // Returns the string of an extension that will do all necessary coord transfomations needed + // when reading the fragment position. If such an extension does not exisits, this function + // returns a nullptr, and all transforms of the frag position must be done manually in the + // shader. + const char* fragCoordConventionsExtensionString() const { + return fFragCoordConventionsExtensionString; + } + + // This returns the name of an extension that must be enabled in the shader, if such a thing is + // required in order to use a secondary output in the shader. This returns a nullptr if no such + // extension is required. However, the return value of this function does not say whether dual + // source blending is supported. + const char* secondaryOutputExtensionString() const { return fSecondaryOutputExtensionString; } + + // This returns the name of an extension that must be enabled in the shader to support external + // textures. In some cases, two extensions must be enabled - the second extension is returned + // by secondExternalTextureExtensionString(). If that function returns nullptr, then only one + // extension is required. + const char* externalTextureExtensionString() const { + SkASSERT(this->externalTextureSupport()); + return fExternalTextureExtensionString; + } + + const char* secondExternalTextureExtensionString() const { + SkASSERT(this->externalTextureSupport()); + return fSecondExternalTextureExtensionString; + } + + const char* texelBufferExtensionString() const { + SkASSERT(this->texelBufferSupport()); + return fTexelBufferExtensionString; + } + + const char* noperspectiveInterpolationExtensionString() const { + SkASSERT(this->noperspectiveInterpolationSupport()); + return fNoPerspectiveInterpolationExtensionString; + } + + const char* imageLoadStoreExtensionString() const { + SkASSERT(this->imageLoadStoreSupport()); + return fImageLoadStoreExtensionString; + } + + int maxVertexSamplers() const { return fMaxVertexSamplers; } + + int maxGeometrySamplers() const { return fMaxGeometrySamplers; } + + int maxFragmentSamplers() const { return fMaxFragmentSamplers; } + + int maxCombinedSamplers() const { return fMaxCombinedSamplers; } + + /** + * In general using multiple texture units for image rendering seems to be a win at smaller + * sizes of dst rects and a loss at larger sizes. Dst rects above this pixel area threshold will + * not use multitexturing. + */ + size_t disableImageMultitexturingDstRectAreaThreshold() const { + return fDisableImageMultitexturingDstRectAreaThreshold; + } + + /** + * Given a texture's config, this determines what swizzle must be appended to accesses to the + * texture in generated shader code. Swizzling may be implemented in texture parameters or a + * sampler rather than in the shader. In this case the returned swizzle will always be "rgba". + */ + const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const { + return fConfigTextureSwizzle[config]; + } + + /** Swizzle that should occur on the fragment shader outputs for a given config. */ + const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const { + return fConfigOutputSwizzle[config]; + } + + GrGLSLGeneration generation() const { return fGLSLGeneration; } + +private: + void applyOptionsOverrides(const GrContextOptions& options); + + GrGLSLGeneration fGLSLGeneration; + + bool fShaderDerivativeSupport : 1; + bool fGeometryShaderSupport : 1; + bool fGSInvocationsSupport : 1; + bool fPathRenderingSupport : 1; + bool fDstReadInShaderSupport : 1; + bool fDualSourceBlendingSupport : 1; + bool fIntegerSupport : 1; + bool fTexelBufferSupport : 1; + bool fImageLoadStoreSupport : 1; + bool fDropsTileOnZeroDivide : 1; + bool fFBFetchSupport : 1; + bool fFBFetchNeedsCustomOutput : 1; + bool fUsesPrecisionModifiers : 1; + bool fFlatInterpolationSupport : 1; + bool fPreferFlatInterpolation : 1; + bool fNoPerspectiveInterpolationSupport : 1; + bool fExternalTextureSupport : 1; + bool fTexelFetchSupport : 1; + bool fVertexIDSupport : 1; + bool fFPManipulationSupport : 1; + bool fFloatIs32Bits : 1; + bool fHalfIs32Bits : 1; + + // Used for specific driver bug work arounds + bool fCanUseAnyFunctionInShader : 1; + bool fCanUseMinAndAbsTogether : 1; + bool fCanUseFractForNegativeValues : 1; + bool fMustForceNegatedAtanParamToFloat : 1; + bool fAtan2ImplementedAsAtanYOverX : 1; + bool fMustDoOpBetweenFloorAndAbs : 1; + bool fRequiresLocalOutputColorForFBFetch : 1; + bool fMustObfuscateUniformColor : 1; + bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1; + bool fCanUseFragCoord : 1; + bool fInterpolantsAreInaccurate : 1; + bool fIncompleteShortIntPrecision : 1; + + const char* fVersionDeclString; + + const char* fShaderDerivativeExtensionString; + const char* fGeometryShaderExtensionString; + const char* fGSInvocationsExtensionString; + const char* fFragCoordConventionsExtensionString; + const char* fSecondaryOutputExtensionString; + const char* fExternalTextureExtensionString; + const char* fSecondExternalTextureExtensionString; + const char* fTexelBufferExtensionString; + const char* fNoPerspectiveInterpolationExtensionString; + const char* fImageLoadStoreExtensionString; + + const char* fFBFetchColorName; + const char* fFBFetchExtensionString; + + int fMaxVertexSamplers; + int fMaxGeometrySamplers; + int fMaxFragmentSamplers; + int fMaxCombinedSamplers; + + size_t fDisableImageMultitexturingDstRectAreaThreshold; + + AdvBlendEqInteraction fAdvBlendEqInteraction; + + GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt]; + GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt]; + + friend class GrCaps; // For initialization. + friend class GrGLCaps; + friend class GrMockCaps; + friend class GrMtlCaps; + friend class GrVkCaps; + friend class SkSL::ShaderCapsFactory; +}; + +#endif diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp index 56d6d7de6a..25093cbf72 100644 --- a/src/gpu/GrSurfaceContext.cpp +++ b/src/gpu/GrSurfaceContext.cpp @@ -6,12 +6,10 @@ */ #include "GrSurfaceContext.h" - #include "GrContextPriv.h" #include "GrDrawingManager.h" #include "GrOpList.h" #include "SkGr.h" - #include "../private/GrAuditTrail.h" #define ASSERT_SINGLE_OWNER \ @@ -87,10 +85,11 @@ bool GrSurfaceContext::copy(GrSurfaceProxy* src, const SkIRect& srcRect, const S SkDEBUGCODE(this->validate();) GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrSurfaceContext::copy"); - if (!fContext->caps()->canCopySurface(this->asSurfaceProxy(), src, srcRect, dstPoint)) { + if (!fContext->contextPriv().caps()->canCopySurface(this->asSurfaceProxy(), src, srcRect, + dstPoint)) { return false; } - return this->getOpList()->copySurface(*fContext->caps(), - this->asSurfaceProxy(), src, srcRect, dstPoint); + return this->getOpList()->copySurface(*fContext->contextPriv().caps(), this->asSurfaceProxy(), + src, srcRect, dstPoint); } diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp index e39937d356..cc61533044 100644 --- a/src/gpu/GrTextureAdjuster.cpp +++ b/src/gpu/GrTextureAdjuster.cpp @@ -6,7 +6,6 @@ */ #include "GrTextureAdjuster.h" - #include "GrColorSpaceXform.h" #include "GrContext.h" #include "GrContextPriv.h" @@ -81,12 +80,12 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::onRefTextureProxyForParams( if (texColorSpace) { *texColorSpace = sk_ref_sp(fColorSpace); } - SkASSERT(this->width() <= fContext->caps()->maxTextureSize() && - this->height() <= fContext->caps()->maxTextureSize()); + SkASSERT(this->width() <= fContext->contextPriv().caps()->maxTextureSize() && + this->height() <= fContext->contextPriv().caps()->maxTextureSize()); - if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), - proxy.get(), proxy->width(), proxy->height(), - params, ©Params, scaleAdjust)) { + if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), proxy.get(), + proxy->width(), proxy->height(), params, ©Params, + scaleAdjust)) { return proxy; } diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp index b4649980a7..58ab38de97 100644 --- a/src/gpu/GrTextureMaker.cpp +++ b/src/gpu/GrTextureMaker.cpp @@ -17,15 +17,15 @@ sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSampler SkColorSpace* dstColorSpace, sk_sp<SkColorSpace>* texColorSpace, SkScalar scaleAdjust[2]) { - if (this->width() > fContext->caps()->maxTextureSize() || - this->height() > fContext->caps()->maxTextureSize()) { + if (this->width() > fContext->contextPriv().caps()->maxTextureSize() || + this->height() > fContext->contextPriv().caps()->maxTextureSize()) { return nullptr; } CopyParams copyParams; bool willBeMipped = params.filter() == GrSamplerState::Filter::kMipMap; - if (!fContext->caps()->mipMapSupport()) { + if (!fContext->contextPriv().caps()->mipMapSupport()) { willBeMipped = false; } @@ -36,15 +36,15 @@ sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSampler sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace, AllowedTexGenType::kCheap)); if (original) { - if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), original.get(), - original->width(), original->height(), - params, ©Params, scaleAdjust)) { + if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), original.get(), + original->width(), original->height(), params, + ©Params, scaleAdjust)) { return original; } } else { - if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), nullptr, - this->width(), this->height(), - params, ©Params, scaleAdjust)) { + if (!GrGpu::IsACopyNeededForTextureParams(fContext->contextPriv().caps(), nullptr, + this->width(), this->height(), params, + ©Params, scaleAdjust)) { return this->refOriginalTextureProxy(willBeMipped, dstColorSpace, AllowedTexGenType::kAny); } diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index b79d4a7eb7..bb85aabbbb 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -138,7 +138,7 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS // Otherwise, we do our shader math to go from YUV -> sRGB, manually convert sRGB -> Linear, // then let the HW convert Linear -> sRGB. if (GrPixelConfigIsSRGB(desc.fConfig)) { - if (ctx->caps()->srgbWriteControl()) { + if (ctx->contextPriv().caps()->srgbWriteControl()) { paint.setDisableOutputConversionToSRGB(true); } else { paint.addColorFragmentProcessor(GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear, diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index f22fbcf260..a08c0e5600 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -157,7 +157,7 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext( return nullptr; } - GrPixelConfig config = SkImageInfo2GrPixelConfig(origInfo, *context->caps()); + GrPixelConfig config = SkImageInfo2GrPixelConfig(origInfo, *context->contextPriv().caps()); if (kUnknown_GrPixelConfig == config) { return nullptr; } @@ -769,7 +769,7 @@ bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr } samplerState.setFilterMode(textureFilterMode); - int maxTileSize = fContext->caps()->maxTileSize() - 2 * tileFilterPad; + int maxTileSize = this->caps()->maxTileSize() - 2 * tileFilterPad; // these are output, which we safely ignore, as we just want to know the predicate int outTileSize; @@ -789,7 +789,7 @@ void SkGpuDevice::drawBitmap(const SkBitmap& bitmap, SkMatrix viewMatrix; viewMatrix.setConcat(this->ctm(), m); - int maxTileSize = fContext->caps()->maxTileSize(); + int maxTileSize = this->caps()->maxTileSize(); // The tile code path doesn't currently support AA, so if the paint asked for aa and we could // draw untiled, then we bypass checking for tiling purely for optimization reasons. @@ -821,7 +821,7 @@ void SkGpuDevice::drawBitmap(const SkBitmap& bitmap, } samplerState.setFilterMode(textureFilterMode); - int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFilterPad; + int maxTileSizeForFilter = this->caps()->maxTileSize() - 2 * tileFilterPad; if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), viewMatrix, SkMatrix::I(), samplerState, &srcRect, maxTileSizeForFilter, &tileSize, &clippedSrcRect)) { @@ -968,11 +968,11 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap, bool bicubic, bool needsTextureDomain) { // We should have already handled bitmaps larger than the max texture size. - SkASSERT(bitmap.width() <= fContext->caps()->maxTextureSize() && - bitmap.height() <= fContext->caps()->maxTextureSize()); + SkASSERT(bitmap.width() <= this->caps()->maxTextureSize() && + bitmap.height() <= this->caps()->maxTextureSize()); // We should be respecting the max tile size by the time we get here. - SkASSERT(bitmap.width() <= fContext->caps()->maxTileSize() && - bitmap.height() <= fContext->caps()->maxTileSize()); + SkASSERT(bitmap.width() <= this->caps()->maxTileSize() && + bitmap.height() <= this->caps()->maxTileSize()); SkASSERT(!samplerState.isRepeated()); SkScalar scales[2] = {1.f, 1.f}; @@ -1148,7 +1148,7 @@ void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap, } } - int maxTileSize = fContext->caps()->maxTileSize(); + int maxTileSize = this->caps()->maxTileSize(); // The tile code path doesn't currently support AA, so if the paint asked for aa and we could // draw untiled, then we bypass checking for tiling purely for optimization reasons. @@ -1179,7 +1179,7 @@ void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap, } sampleState.setFilterMode(textureFilterMode); - int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFilterPad; + int maxTileSizeForFilter = this->caps()->maxTileSize() - 2 * tileFilterPad; if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), this->ctm(), srcToDstMatrix, sampleState, src, maxTileSizeForFilter, &tileSize, &clippedSrcRect)) { diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index f415f3db61..d98dbffe1d 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -8,16 +8,17 @@ #ifndef SkGpuDevice_DEFINED #define SkGpuDevice_DEFINED -#include "SkGr.h" +#include "GrClipStackClip.h" +#include "GrContext.h" +#include "GrContextPriv.h" +#include "GrRenderTargetContext.h" +#include "GrTypes.h" #include "SkBitmap.h" #include "SkClipStackDevice.h" +#include "SkGr.h" #include "SkPicture.h" #include "SkRegion.h" #include "SkSurface.h" -#include "GrClipStackClip.h" -#include "GrRenderTargetContext.h" -#include "GrContext.h" -#include "GrTypes.h" class GrAccelData; class GrTextureMaker; @@ -157,6 +158,8 @@ private: GrClipStackClip clip() const { return GrClipStackClip(&this->cs()); } + const GrCaps* caps() const { return fContext->contextPriv().caps(); } + /** * Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's * matrix, clip, and the device's render target has already been set on GrContext. diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 60586ea503..a37523fc06 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -110,7 +110,7 @@ void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pix sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx, GrTextureProxy* baseProxy) { SkASSERT(baseProxy); - if (!ctx->caps()->isConfigCopyable(baseProxy->config())) { + if (!ctx->contextPriv().caps()->isConfigCopyable(baseProxy->config())) { return nullptr; } diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 382457d5d7..e996588ee0 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -6,8 +6,8 @@ */ #include "GrGLRenderTarget.h" - #include "GrContext.h" +#include "GrContextPriv.h" #include "GrGLGpu.h" #include "GrGLUtil.h" #include "GrGpuResourcePriv.h" @@ -187,7 +187,7 @@ GrGLGpu* GrGLRenderTarget::getGLGpu() const { } bool GrGLRenderTarget::canAttemptStencilAttachment() const { - if (this->getGpu()->getContext()->caps()->avoidStencilBuffers()) { + if (this->getGpu()->getContext()->contextPriv().caps()->avoidStencilBuffers()) { return false; } diff --git a/src/gpu/gl/GrGLTextureRenderTarget.cpp b/src/gpu/gl/GrGLTextureRenderTarget.cpp index 049cb31a9b..a9d7f14e39 100644 --- a/src/gpu/gl/GrGLTextureRenderTarget.cpp +++ b/src/gpu/gl/GrGLTextureRenderTarget.cpp @@ -6,8 +6,8 @@ */ #include "GrGLTextureRenderTarget.h" - #include "GrContext.h" +#include "GrContextPriv.h" #include "GrGLGpu.h" #include "GrTexturePriv.h" #include "SkTraceMemoryDump.h" @@ -52,7 +52,7 @@ void GrGLTextureRenderTarget::dumpMemoryStatistics( bool GrGLTextureRenderTarget::canAttemptStencilAttachment() const { // The RT FBO of GrGLTextureRenderTarget is never created from a // wrapped FBO, so we only care about the flag. - return !this->getGpu()->getContext()->caps()->avoidStencilBuffers(); + return !this->getGpu()->getContext()->contextPriv().caps()->avoidStencilBuffers(); } sk_sp<GrGLTextureRenderTarget> GrGLTextureRenderTarget::MakeWrapped( diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp index 329fa81dfa..dded70a7f7 100644 --- a/src/gpu/ops/GrDrawVerticesOp.cpp +++ b/src/gpu/ops/GrDrawVerticesOp.cpp @@ -6,6 +6,7 @@ */ #include "GrDrawVerticesOp.h" +#include "GrCaps.h" #include "GrDefaultGeoProcFactory.h" #include "GrOpFlushState.h" #include "SkGr.h" @@ -374,7 +375,7 @@ GR_DRAW_OP_TEST_DEFINE(GrDrawVerticesOp) { do { type = GrPrimitiveType(random->nextULessThan(kNumGrPrimitiveTypes)); } while (GrPrimTypeRequiresGeometryShaderSupport(type) && - !context->caps()->shaderCaps()->geometryShaderSupport()); + !context->contextPriv().caps()->shaderCaps()->geometryShaderSupport()); uint32_t primitiveCount = random->nextRangeU(1, 100); diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp index a2e62430ce..a7700cb17d 100644 --- a/src/gpu/text/GrAtlasTextContext.cpp +++ b/src/gpu/text/GrAtlasTextContext.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ #include "GrAtlasTextContext.h" +#include "GrCaps.h" #include "GrContext.h" #include "GrContextPriv.h" #include "GrSDFMaskFilter.h" @@ -154,8 +155,8 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t textBlobCache->remove(cacheBlob.get()); cacheBlob = textBlobCache->makeCachedBlob(blob, key, blurRec, skPaint); this->regenerateTextBlob(cacheBlob.get(), glyphCache, - *context->caps()->shaderCaps(), paint, scalerContextFlags, - viewMatrix, props, blob, x, y, drawFilter); + *context->contextPriv().caps()->shaderCaps(), paint, + scalerContextFlags, viewMatrix, props, blob, x, y, drawFilter); } else { textBlobCache->makeMRU(cacheBlob.get()); @@ -165,9 +166,9 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); sk_sp<GrAtlasTextBlob> sanityBlob(textBlobCache->makeBlob(glyphCount, runCount)); sanityBlob->setupKey(key, blurRec, skPaint); - this->regenerateTextBlob(sanityBlob.get(), glyphCache, - *context->caps()->shaderCaps(), paint, scalerContextFlags, - viewMatrix, props, blob, x, y, drawFilter); + this->regenerateTextBlob( + sanityBlob.get(), glyphCache, *context->contextPriv().caps()->shaderCaps(), + paint, scalerContextFlags, viewMatrix, props, blob, x, y, drawFilter); GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob); } } @@ -178,8 +179,8 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* t cacheBlob = textBlobCache->makeBlob(blob); } this->regenerateTextBlob(cacheBlob.get(), glyphCache, - *context->caps()->shaderCaps(), paint, scalerContextFlags, - viewMatrix, props, blob, x, y, drawFilter); + *context->contextPriv().caps()->shaderCaps(), paint, + scalerContextFlags, viewMatrix, props, blob, x, y, drawFilter); } cacheBlob->flush(target, props, fDistanceAdjustTable.get(), paint, @@ -326,11 +327,10 @@ void GrAtlasTextContext::drawText(GrContext* context, GrTextUtils::Target* targe auto textBlobCache = context->contextPriv().getTextBlobCache(); GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo()); - sk_sp<GrAtlasTextBlob> blob( - this->makeDrawTextBlob(textBlobCache, glyphCache, - *context->caps()->shaderCaps(), paint, - ComputeScalerContextFlags(target->colorSpaceInfo()), - viewMatrix, props, text, byteLength, x, y)); + sk_sp<GrAtlasTextBlob> blob(this->makeDrawTextBlob( + textBlobCache, glyphCache, *context->contextPriv().caps()->shaderCaps(), paint, + ComputeScalerContextFlags(target->colorSpaceInfo()), viewMatrix, props, text, + byteLength, x, y)); if (blob) { blob->flush(target, props, fDistanceAdjustTable.get(), paint, clip, viewMatrix, regionClipBounds, x, y); @@ -352,8 +352,7 @@ void GrAtlasTextContext::drawPosText(GrContext* context, GrTextUtils::Target* ta auto textBlobCache = context->contextPriv().getTextBlobCache(); sk_sp<GrAtlasTextBlob> blob(this->makeDrawPosTextBlob( - textBlobCache, glyphCache, - *context->caps()->shaderCaps(), paint, + textBlobCache, glyphCache, *context->contextPriv().caps()->shaderCaps(), paint, ComputeScalerContextFlags(target->colorSpaceInfo()), viewMatrix, props, text, byteLength, pos, scalarsPerPosition, offset)); if (blob) { @@ -951,12 +950,10 @@ std::unique_ptr<GrDrawOp> GrAtlasTextContext::createOp_TestingOnly( // right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to // test the text op with this unit test, that is okay. sk_sp<GrAtlasTextBlob> blob(textContext->makeDrawTextBlob( - context->contextPriv().getTextBlobCache(), glyphCache, - *context->caps()->shaderCaps(), utilsPaint, - GrAtlasTextContext::kTextBlobOpScalerContextFlags, - viewMatrix, surfaceProps, text, - static_cast<size_t>(textLen), - SkIntToScalar(x), SkIntToScalar(y))); + context->contextPriv().getTextBlobCache(), glyphCache, + *context->contextPriv().caps()->shaderCaps(), utilsPaint, + GrAtlasTextContext::kTextBlobOpScalerContextFlags, viewMatrix, surfaceProps, text, + static_cast<size_t>(textLen), SkIntToScalar(x), SkIntToScalar(y))); return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, surfaceProps, textContext->dfAdjustTable(), rtc->textTarget()); |