diff options
Diffstat (limited to 'src')
40 files changed, 846 insertions, 166 deletions
diff --git a/src/atlastext/SkAtlasTextTarget.cpp b/src/atlastext/SkAtlasTextTarget.cpp index c1a21b04a2..39f0c1b1d6 100644 --- a/src/atlastext/SkAtlasTextTarget.cpp +++ b/src/atlastext/SkAtlasTextTarget.cpp @@ -148,7 +148,7 @@ void SkInternalAtlasTextTarget::addDrawOp(const GrClip& clip, std::unique_ptr<Gr if (op->maskType() != GrAtlasTextOp::kGrayscaleDistanceField_MaskType) { return; } - const GrCaps& caps = *this->context()->internal().grContext()->caps(); + const GrCaps& caps = *this->context()->internal().grContext()->contextPriv().caps(); op->finalizeForTextTarget(fColor, caps); int n = SkTMin(kMaxBatchLookBack, fOps.count()); for (int i = 0; i < n; ++i) { diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp index b75fd16f6c..d716c33f68 100644 --- a/src/core/SkBlurMF.cpp +++ b/src/core/SkBlurMF.cpp @@ -21,6 +21,7 @@ #if SK_SUPPORT_GPU #include "GrClip.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "GrFragmentProcessor.h" #include "GrRenderTargetContext.h" #include "GrResourceProvider.h" @@ -758,8 +759,8 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, SkScalar pad = 3.0f * xformedSigma; rect.outset(pad, pad); - fp = GrRectBlurEffect::Make(proxyProvider, *context->caps()->shaderCaps(), rect, - xformedSigma); + fp = GrRectBlurEffect::Make(proxyProvider, *context->contextPriv().caps()->shaderCaps(), + rect, xformedSigma); } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height())) { fp = GrCircleBlurFragmentProcessor::Make(proxyProvider, rect, xformedSigma); @@ -812,7 +813,7 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, SkScalar pad = 3.0f * xformedSigma; const SkRect dstCoverageRect = devRRect.rect().makeOutset(pad, pad); - fp = GrRectBlurEffect::Make(proxyProvider, *context->caps()->shaderCaps(), + fp = GrRectBlurEffect::Make(proxyProvider, *context->contextPriv().caps()->shaderCaps(), dstCoverageRect, xformedSigma); } else { fp = GrCircleBlurFragmentProcessor::Make(proxyProvider, diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp index d390228e4a..d13fd3915e 100644 --- a/src/core/SkDeferredDisplayListRecorder.cpp +++ b/src/core/SkDeferredDisplayListRecorder.cpp @@ -102,11 +102,11 @@ bool SkDeferredDisplayListRecorder::init() { // DDL is being replayed into. GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone; - if (fContext->caps()->usesMixedSamples() && desc.fSampleCnt > 1 && !usesGLFBO0) { + if (fContext->contextPriv().caps()->usesMixedSamples() && desc.fSampleCnt > 1 && !usesGLFBO0) { // In GL, FBO 0 never supports mixed samples surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled; } - if (fContext->caps()->maxWindowRectangles() > 0 && !usesGLFBO0) { + if (fContext->contextPriv().caps()->maxWindowRectangles() > 0 && !usesGLFBO0) { // In GL, FBO 0 never supports window rectangles surfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport; } diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp index c75ff3e875..a2f95adcf8 100644 --- a/src/core/SkGpuBlurUtils.cpp +++ b/src/core/SkGpuBlurUtils.cpp @@ -455,7 +455,7 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context, int scaleFactorX, radiusX; int scaleFactorY, radiusY; - int maxTextureSize = context->caps()->maxTextureSize(); + int maxTextureSize = context->contextPriv().caps()->maxTextureSize(); sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); SkASSERT(sigmaX || sigmaY); diff --git a/src/core/SkSurfaceCharacterization.cpp b/src/core/SkSurfaceCharacterization.cpp index 74160d2b94..d71559f58f 100644 --- a/src/core/SkSurfaceCharacterization.cpp +++ b/src/core/SkSurfaceCharacterization.cpp @@ -8,6 +8,7 @@ #include "SkSurfaceCharacterization.h" #if SK_SUPPORT_GPU +#include "GrCaps.h" #include "GrContextThreadSafeProxyPriv.h" bool SkSurfaceCharacterization::operator==(const SkSurfaceCharacterization& other) const { diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 8cf3728c81..47d6ae2d8c 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -443,7 +443,7 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context, desc.fWidth = bitmap.width(); desc.fHeight = 128; desc.fRowHeight = bitmap.height(); - desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps()); + desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->contextPriv().caps()); if (kUnknown_GrPixelConfig == desc.fConfig) { return nullptr; 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()); diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 17a0a25f5a..62b97ae131 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -374,7 +374,7 @@ bool validate_backend_texture(GrContext* ctx, const GrBackendTexture& tex, GrPix return false; } - return ctx->caps()->validateBackendTexture(tex, ct, config); + return ctx->contextPriv().caps()->validateBackendTexture(tex, ct, config); } sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx, @@ -694,7 +694,8 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context, return nullptr; } GrPixelConfig config = kUnknown_GrPixelConfig; - if (!context->caps()->getConfigFromBackendFormat(backendFormat, colorType, &config)) { + if (!context->contextPriv().caps()->getConfigFromBackendFormat(backendFormat, colorType, + &config)) { return nullptr; } @@ -748,12 +749,13 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk } // Some backends or drivers don't support (safely) moving resources between contexts - if (!context || !context->caps()->crossContextTextureSupport()) { + if (!context || !context->contextPriv().caps()->crossContextTextureSupport()) { return codecImage; } - if (limitToMaxTextureSize && (codecImage->width() > context->caps()->maxTextureSize() || - codecImage->height() > context->caps()->maxTextureSize())) { + auto maxTextureSize = context->contextPriv().caps()->maxTextureSize(); + if (limitToMaxTextureSize && + (codecImage->width() > maxTextureSize || codecImage->height() > maxTextureSize)) { SkAutoPixmapStorage pmap; SkImageInfo info = as_IB(codecImage)->onImageInfo(); if (!dstColorSpace) { @@ -801,7 +803,7 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrContext* context, SkColorSpace* dstColorSpace, bool limitToMaxTextureSize) { // Some backends or drivers don't support (safely) moving resources between contexts - if (!context || !context->caps()->crossContextTextureSupport()) { + if (!context || !context->contextPriv().caps()->crossContextTextureSupport()) { return SkImage::MakeRasterCopy(originalPixmap); } @@ -814,7 +816,7 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrContext* context, const SkPixmap* pixmap = &originalPixmap; SkAutoPixmapStorage resized; - int maxTextureSize = context->caps()->maxTextureSize(); + int maxTextureSize = context->contextPriv().caps()->maxTextureSize(); int maxDim = SkTMax(originalPixmap.width(), originalPixmap.height()); if (limitToMaxTextureSize && maxDim > maxTextureSize) { float scale = static_cast<float>(maxTextureSize) / maxDim; diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp index 035ddccfb8..9ca9d0d782 100644 --- a/src/image/SkImage_Lazy.cpp +++ b/src/image/SkImage_Lazy.cpp @@ -724,7 +724,7 @@ sk_sp<SkColorSpace> SkImage_Lazy::getColorSpace(GrContext* ctx, SkColorSpace* ds // may want to know what space the image data is in, so return it. return fInfo.refColorSpace(); } else { - CachedFormat format = this->chooseCacheFormat(dstColorSpace, ctx->caps()); + CachedFormat format = this->chooseCacheFormat(dstColorSpace, ctx->contextPriv().caps()); SkImageInfo cacheInfo = this->buildCacheInfo(format); return cacheInfo.refColorSpace(); } @@ -759,7 +759,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx, // Determine which cached format we're going to use (which may involve decoding to a different // info than the generator provides). - CachedFormat format = this->chooseCacheFormat(dstColorSpace, ctx->caps()); + CachedFormat format = this->chooseCacheFormat(dstColorSpace, ctx->contextPriv().caps()); // Fold the cache format into our texture key GrUniqueKey key; @@ -808,7 +808,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx, // 3. Ask the generator to return YUV planes, which the GPU can convert. If we will be mipping // the texture we fall through here and have the CPU generate the mip maps for us. if (!proxy && !willBeMipped && !ctx->contextPriv().disableGpuYUVConversion()) { - const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(cacheInfo, *ctx->caps()); + const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(cacheInfo, *ctx->contextPriv().caps()); ScopedGenerator generator(fSharedGenerator); Generator_GrYUVProvider provider(generator); diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index c81fc28417..b4e6acf0c2 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -6,22 +6,21 @@ */ #include "SkSurface_Gpu.h" - #include "GrBackendSurface.h" +#include "GrCaps.h" #include "GrContextPriv.h" #include "GrRenderTarget.h" #include "GrRenderTargetContextPriv.h" #include "GrRenderTargetProxyPriv.h" #include "GrTexture.h" - #include "SkCanvas.h" #include "SkDeferredDisplayList.h" #include "SkGpuDevice.h" +#include "SkImagePriv.h" #include "SkImage_Base.h" #include "SkImage_Gpu.h" -#include "SkImagePriv.h" -#include "SkSurface_Base.h" #include "SkSurfaceCharacterization.h" +#include "SkSurface_Base.h" #if SK_SUPPORT_GPU @@ -334,7 +333,7 @@ sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* context, return nullptr; } - if (!SkSurface_Gpu::Valid(context->caps(), c.config(), c.colorSpace())) { + if (!SkSurface_Gpu::Valid(context->contextPriv().caps(), c.config(), c.colorSpace())) { return nullptr; } @@ -389,7 +388,7 @@ sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* ctx, SkBudgeted budgeted sampleCount = SkTMax(1, sampleCount); GrMipMapped mipMapped = shouldCreateWithMips ? GrMipMapped::kYes : GrMipMapped::kNo; - if (!ctx->caps()->mipMapSupport()) { + if (!ctx->contextPriv().caps()->mipMapSupport()) { mipMapped = GrMipMapped::kNo; } @@ -433,17 +432,17 @@ bool validate_backend_texture(GrContext* ctx, const GrBackendTexture& tex, GrPix return false; } - if (!ctx->caps()->validateBackendTexture(tex, ct, config)) { + if (!ctx->contextPriv().caps()->validateBackendTexture(tex, ct, config)) { return false; } // We don't require that the client gave us an exact valid sample cnt. However, it must be // less than the max supported sample count and 1 if MSAA is unsupported for the color type. - if (!ctx->caps()->getRenderTargetSampleCount(sampleCnt, *config)) { + if (!ctx->contextPriv().caps()->getRenderTargetSampleCount(sampleCnt, *config)) { return false; } - if (texturable && !ctx->caps()->isConfigTexturable(*config)) { + if (texturable && !ctx->contextPriv().caps()->isConfigTexturable(*config)) { return false; } return true; @@ -467,7 +466,7 @@ sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext* context, const GrB if (!context) { return nullptr; } - if (!SkSurface_Gpu::Valid(context->caps(), texCopy.config(), colorSpace.get())) { + if (!SkSurface_Gpu::Valid(context->contextPriv().caps(), texCopy.config(), colorSpace.get())) { return nullptr; } sampleCnt = SkTMax(1, sampleCnt); @@ -501,15 +500,15 @@ bool validate_backend_render_target(GrContext* ctx, const GrBackendRenderTarget& return false; } - if (!ctx->caps()->validateBackendRenderTarget(rt, ct, config)) { + if (!ctx->contextPriv().caps()->validateBackendRenderTarget(rt, ct, config)) { return false; } if (rt.sampleCnt() > 1) { - if (ctx->caps()->maxRenderTargetSampleCount(*config) <= 1) { + if (ctx->contextPriv().caps()->maxRenderTargetSampleCount(*config) <= 1) { return false; } - } else if (!ctx->caps()->isConfigRenderable(*config)) { + } else if (!ctx->contextPriv().caps()->isConfigRenderable(*config)) { return false; } @@ -530,7 +529,7 @@ sk_sp<SkSurface> SkSurface::MakeFromBackendRenderTarget(GrContext* context, if (!validate_backend_render_target(context, rtCopy, &rtCopy.fConfig, colorType, colorSpace)) { return nullptr; } - if (!SkSurface_Gpu::Valid(context->caps(), rtCopy.config(), colorSpace.get())) { + if (!SkSurface_Gpu::Valid(context->contextPriv().caps(), rtCopy.config(), colorSpace.get())) { return nullptr; } @@ -565,7 +564,8 @@ sk_sp<SkSurface> SkSurface::MakeFromBackendTextureAsRenderTarget(GrContext* cont if (!context) { return nullptr; } - if (!tex.isValid() || !SkSurface_Gpu::Valid(context->caps(), tex.config(), colorSpace.get())) { + if (!tex.isValid() || + !SkSurface_Gpu::Valid(context->contextPriv().caps(), tex.config(), colorSpace.get())) { return nullptr; } sampleCnt = SkTMax(1, sampleCnt); diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp index 42f5c3e497..f958814ca1 100644 --- a/src/shaders/SkPictureShader.cpp +++ b/src/shaders/SkPictureShader.cpp @@ -24,6 +24,7 @@ #include "GrCaps.h" #include "GrColorSpaceInfo.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "GrFragmentProcessor.h" #endif @@ -358,7 +359,7 @@ std::unique_ptr<GrFragmentProcessor> SkPictureShader::asFragmentProcessor( const GrFPArgs& args) const { int maxTextureSize = 0; if (args.fContext) { - maxTextureSize = args.fContext->caps()->maxTextureSize(); + maxTextureSize = args.fContext->contextPriv().caps()->maxTextureSize(); } auto lm = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix); diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 7f597cbac2..60e9f2adbf 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -1268,11 +1268,12 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool } else { SkGradientShaderBase::GradientBitmapType bitmapType = SkGradientShaderBase::GradientBitmapType::kLegacy; + auto caps = args.fContext->contextPriv().caps(); if (args.fDstColorSpace) { // Try to use F16 if we can - if (args.fContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) { + if (caps->isConfigTexturable(kRGBA_half_GrPixelConfig)) { bitmapType = SkGradientShaderBase::GradientBitmapType::kHalfFloat; - } else if (args.fContext->caps()->isConfigTexturable(kSRGBA_8888_GrPixelConfig)) { + } else if (caps->isConfigTexturable(kSRGBA_8888_GrPixelConfig)) { bitmapType = SkGradientShaderBase::GradientBitmapType::kSRGB; } else { // This can happen, but only if someone explicitly creates an unsupported @@ -1290,7 +1291,7 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool desc.fWidth = bitmap.width(); desc.fHeight = 32; desc.fRowHeight = bitmap.height(); // always 1 here - desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fContext->caps()); + desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *caps); fAtlas = atlasManager->refAtlas(desc); SkASSERT(fAtlas); diff --git a/src/sksl/SkSLUtil.h b/src/sksl/SkSLUtil.h index 40a5a4774f..eb4fa51df0 100644 --- a/src/sksl/SkSLUtil.h +++ b/src/sksl/SkSLUtil.h @@ -16,7 +16,7 @@ #include "SkSLString.h" #include "SkSLStringStream.h" -#ifndef SKSL_STANDALONE +#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU #include "GrContextOptions.h" #include "GrShaderCaps.h" #endif @@ -31,9 +31,11 @@ #endif // SK_BUILD_FOR_WIN #endif // SKSL_STANDALONE +class GrShaderCaps; + namespace SkSL { -#ifdef SKSL_STANDALONE +#if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU // we're being compiled standalone, so we don't have access to caps... enum GrGLSLGeneration { |