| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrGpu_DEFINED |
| #define GrGpu_DEFINED |
| |
| #include "include/core/SkPath.h" |
| #include "include/core/SkSurface.h" |
| #include "include/gpu/GrTypes.h" |
| #include "include/private/SkTArray.h" |
| #include "src/gpu/GrAllocator.h" |
| #include "src/gpu/GrCaps.h" |
| #include "src/gpu/GrOpsRenderPass.h" |
| #include "src/gpu/GrProgramDesc.h" |
| #include "src/gpu/GrSamplePatternDictionary.h" |
| #include "src/gpu/GrSwizzle.h" |
| #include "src/gpu/GrTextureProducer.h" |
| #include "src/gpu/GrXferProcessor.h" |
| #include <map> |
| |
| class GrBackendRenderTarget; |
| class GrBackendSemaphore; |
| class GrGpuBuffer; |
| class GrContext; |
| struct GrContextOptions; |
| class GrGLContext; |
| class GrMesh; |
| class GrPath; |
| class GrPathRenderer; |
| class GrPathRendererChain; |
| class GrPathRendering; |
| class GrPipeline; |
| class GrPrimitiveProcessor; |
| class GrRenderTarget; |
| class GrSemaphore; |
| class GrStencilAttachment; |
| class GrStencilSettings; |
| class GrSurface; |
| class GrTexture; |
| class SkJSONWriter; |
| |
| class GrGpu : public SkRefCnt { |
| public: |
| GrGpu(GrContext* context); |
| ~GrGpu() override; |
| |
| GrContext* getContext() { return fContext; } |
| const GrContext* getContext() const { return fContext; } |
| |
| /** |
| * Gets the capabilities of the draw target. |
| */ |
| const GrCaps* caps() const { return fCaps.get(); } |
| sk_sp<const GrCaps> refCaps() const { return fCaps; } |
| |
| GrPathRendering* pathRendering() { return fPathRendering.get(); } |
| |
| enum class DisconnectType { |
| // No cleanup should be attempted, immediately cease making backend API calls |
| kAbandon, |
| // Free allocated resources (not known by GrResourceCache) before returning and |
| // ensure no backend backend 3D API calls will be made after disconnect() returns. |
| kCleanup, |
| }; |
| |
| // Called by GrContext when the underlying backend context is already or will be destroyed |
| // before GrContext. |
| virtual void disconnect(DisconnectType); |
| |
| /** |
| * The GrGpu object normally assumes that no outsider is setting state |
| * within the underlying 3D API's context/device/whatever. This call informs |
| * the GrGpu that the state was modified and it shouldn't make assumptions |
| * about the state. |
| */ |
| void markContextDirty(uint32_t state = kAll_GrBackendState) { fResetBits |= state; } |
| |
| /** |
| * Creates a texture object. If renderable is kYes then the returned texture can |
| * be used as a render target by calling GrTexture::asRenderTarget(). Not all |
| * pixel configs can be used as render targets. Support for configs as textures |
| * or render targets can be checked using GrCaps. |
| * |
| * @param desc describes the texture to be created. |
| * @param format the format for the texture (not currently used). |
| * @param renderable should the resulting texture be renderable |
| * @param renderTargetSampleCnt The number of samples to use for rendering if renderable is |
| * kYes. If renderable is kNo then this must be 1. |
| * @param budgeted does this texture count against the resource cache budget? |
| * @param isProtected should the texture be created as protected. |
| * @param texels array of mipmap levels containing texel data to load. |
| * If level i has pixels then it is assumed that its dimensions are |
| * max(1, floor(desc.fWidth / 2)) by max(1, floor(desc.fHeight / 2)). |
| * If texels[i].fPixels == nullptr for all i <= mipLevelCount or |
| * mipLevelCount is 0 then the texture's contents are uninitialized. |
| * If a level has non-null pixels, its row bytes must be a multiple of the |
| * config's bytes-per-pixel. The row bytes must be tight to the |
| * level width if !caps->writePixelsRowBytesSupport(). |
| * If mipLevelCount > 1 and texels[i].fPixels != nullptr for any i > 0 |
| * then all levels must have non-null pixels. All levels must have |
| * non-null pixels if GrCaps::createTextureMustSpecifyAllLevels() is true. |
| * @param textureColorType The color type interpretation of the texture for the purpose of |
| * of uploading texel data. |
| * @param srcColorType The color type of data in texels[]. |
| * @param texelLevelCount the number of levels in 'texels'. May be 0, 1, or |
| * floor(max((log2(desc.fWidth), log2(desc.fHeight)))). It must be the |
| * latter if GrCaps::createTextureMustSpecifyAllLevels() is true. |
| * @return The texture object if successful, otherwise nullptr. |
| */ |
| sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, |
| const GrBackendFormat& format, |
| GrRenderable renderable, |
| int renderTargetSampleCnt, |
| SkBudgeted, |
| GrProtected isProtected, |
| GrColorType textureColorType, |
| GrColorType srcColorType, |
| const GrMipLevel texels[], |
| int texelLevelCount); |
| |
| /** |
| * Simplified createTexture() interface for when there is no initial texel data to upload. |
| */ |
| sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, |
| const GrBackendFormat& format, |
| GrRenderable renderable, |
| int renderTargetSampleCnt, |
| GrMipMapped, |
| SkBudgeted budgeted, |
| GrProtected isProtected); |
| |
| sk_sp<GrTexture> createCompressedTexture(int width, int height, const GrBackendFormat&, |
| SkImage::CompressionType, SkBudgeted, const void* data, |
| size_t dataSize); |
| |
| /** |
| * Implements GrResourceProvider::wrapBackendTexture |
| */ |
| sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture&, GrColorType, |
| GrWrapOwnership, GrWrapCacheable, GrIOType); |
| |
| /** |
| * Implements GrResourceProvider::wrapRenderableBackendTexture |
| */ |
| sk_sp<GrTexture> wrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt, |
| GrColorType, GrWrapOwnership, GrWrapCacheable); |
| |
| /** |
| * Implements GrResourceProvider::wrapBackendRenderTarget |
| */ |
| sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTarget&, |
| GrColorType colorType); |
| |
| /** |
| * Implements GrResourceProvider::wrapBackendTextureAsRenderTarget |
| */ |
| sk_sp<GrRenderTarget> wrapBackendTextureAsRenderTarget(const GrBackendTexture&, |
| int sampleCnt, |
| GrColorType colorType); |
| |
| /** |
| * Implements GrResourceProvider::wrapVulkanSecondaryCBAsRenderTarget |
| */ |
| sk_sp<GrRenderTarget> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, |
| const GrVkDrawableInfo&); |
| |
| /** |
| * Creates a buffer in GPU memory. For a client-side buffer use GrBuffer::CreateCPUBacked. |
| * |
| * @param size size of buffer to create. |
| * @param intendedType hint to the graphics subsystem about what the buffer will be used for. |
| * @param accessPattern hint to the graphics subsystem about how the data will be accessed. |
| * @param data optional data with which to initialize the buffer. |
| * |
| * @return the buffer if successful, otherwise nullptr. |
| */ |
| sk_sp<GrGpuBuffer> createBuffer(size_t size, GrGpuBufferType intendedType, |
| GrAccessPattern accessPattern, const void* data = nullptr); |
| |
| enum class ForExternalIO : bool { |
| kYes = true, |
| kNo = false |
| }; |
| |
| /** |
| * Resolves MSAA. |
| */ |
| void resolveRenderTarget(GrRenderTarget*, const SkIRect& resolveRect, GrSurfaceOrigin, |
| ForExternalIO); |
| |
| /** |
| * Uses the base of the texture to recompute the contents of the other levels. |
| */ |
| bool regenerateMipMapLevels(GrTexture*); |
| |
| /** |
| * If the backend API has stateful texture bindings, this resets them back to defaults. |
| */ |
| void resetTextureBindings(); |
| |
| /** |
| * Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed. |
| * |
| * @param surface The surface to read from |
| * @param left left edge of the rectangle to read (inclusive) |
| * @param top top edge of the rectangle to read (inclusive) |
| * @param width width of rectangle to read in pixels. |
| * @param height height of rectangle to read in pixels. |
| * @param surfaceColorType the color type for this use of the surface. |
| * @param dstColorType the color type of the destination buffer. |
| * @param buffer memory to read the rectangle into. |
| * @param rowBytes the number of bytes between consecutive rows. Must be a multiple of |
| * dstColorType's bytes-per-pixel. Must be tight to width if |
| * !caps->readPixelsRowBytesSupport(). |
| * |
| * @return true if the read succeeded, false if not. The read can fail |
| * because of the surface doesn't support reading, the color type |
| * is not allowed for the format of the surface or if the rectangle |
| * read is not contained in the surface. |
| */ |
| bool readPixels(GrSurface* surface, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType dstColorType, void* buffer, |
| size_t rowBytes); |
| |
| /** |
| * Updates the pixels in a rectangle of a surface. No sRGB/linear conversions are performed. |
| * |
| * @param surface The surface to write to. |
| * @param left left edge of the rectangle to write (inclusive) |
| * @param top top edge of the rectangle to write (inclusive) |
| * @param width width of rectangle to write in pixels. |
| * @param height height of rectangle to write in pixels. |
| * @param surfaceColorType the color type for this use of the surface. |
| * @param srcColorType the color type of the source buffer. |
| * @param texels array of mipmap levels containing texture data. Row bytes must be a |
| * multiple of srcColorType's bytes-per-pixel. Must be tight to level |
| * width if !caps->writePixelsRowBytesSupport(). |
| * @param mipLevelCount number of levels in 'texels' |
| * @param prepForTexSampling After doing write pixels should the surface be prepared for texture |
| * sampling. This is currently only used by Vulkan for inline uploads |
| * to set that layout back to sampled after doing the upload. Inline |
| * uploads currently can happen between draws in a single op so it is |
| * not trivial to break up the GrOpsTask into two tasks when we see |
| * an inline upload. However, once we are able to support doing that |
| * we can remove this parameter. |
| * |
| * @return true if the write succeeded, false if not. The read can fail |
| * because of the surface doesn't support writing (e.g. read only), |
| * the color type is not allowed for the format of the surface or |
| * if the rectangle written is not contained in the surface. |
| */ |
| bool writePixels(GrSurface* surface, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType srcColorType, |
| const GrMipLevel texels[], int mipLevelCount, bool prepForTexSampling = false); |
| |
| /** |
| * Helper for the case of a single level. |
| */ |
| bool writePixels(GrSurface* surface, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType srcColorType, const void* buffer, |
| size_t rowBytes, bool prepForTexSampling = false) { |
| GrMipLevel mipLevel = {buffer, rowBytes}; |
| return this->writePixels(surface, left, top, width, height, surfaceColorType, srcColorType, |
| &mipLevel, 1, prepForTexSampling); |
| } |
| |
| /** |
| * Updates the pixels in a rectangle of a texture using a buffer. If the texture is MIP mapped, |
| * the base level is written to. |
| * |
| * @param texture The texture to write to. |
| * @param left left edge of the rectangle to write (inclusive) |
| * @param top top edge of the rectangle to write (inclusive) |
| * @param width width of rectangle to write in pixels. |
| * @param height height of rectangle to write in pixels. |
| * @param textureColorType the color type for this use of the surface. |
| * @param bufferColorType the color type of the transfer buffer's pixel data |
| * @param transferBuffer GrBuffer to read pixels from (type must be "kXferCpuToGpu") |
| * @param offset offset from the start of the buffer |
| * @param rowBytes number of bytes between consecutive rows in the buffer. Must be a |
| * multiple of bufferColorType's bytes-per-pixel. Must be tight to width |
| * if !caps->writePixelsRowBytesSupport(). |
| */ |
| bool transferPixelsTo(GrTexture* texture, int left, int top, int width, int height, |
| GrColorType textureColorType, GrColorType bufferColorType, |
| GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes); |
| |
| /** |
| * Reads the pixels from a rectangle of a surface into a buffer. Use |
| * GrCaps::SupportedRead::fOffsetAlignmentForTransferBuffer to determine the requirements for |
| * the buffer offset alignment. If the surface is a MIP mapped texture, the base level is read. |
| * |
| * If successful the row bytes in the buffer is always: |
| * GrColorTypeBytesPerPixel(bufferColorType) * width |
| * |
| * Asserts that the caller has passed a properly aligned offset and that the buffer is |
| * large enough to hold the result |
| * |
| * @param surface The surface to read from. |
| * @param left left edge of the rectangle to read (inclusive) |
| * @param top top edge of the rectangle to read (inclusive) |
| * @param width width of rectangle to read in pixels. |
| * @param height height of rectangle to read in pixels. |
| * @param surfaceColorType the color type for this use of the surface. |
| * @param bufferColorType the color type of the transfer buffer's pixel data |
| * @param transferBuffer GrBuffer to write pixels to (type must be "kXferGpuToCpu") |
| * @param offset offset from the start of the buffer |
| */ |
| bool transferPixelsFrom(GrSurface* surface, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType bufferColorType, |
| GrGpuBuffer* transferBuffer, size_t offset); |
| |
| // Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst |
| // take place at higher levels and this function implement faster copy paths. The rect |
| // and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the |
| // src/dst bounds and non-empty. They must also be in their exact device space coords, including |
| // already being transformed for origin if need be. If canDiscardOutsideDstRect is set to true |
| // then we don't need to preserve any data on the dst surface outside of the copy. |
| bool copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, |
| const SkIPoint& dstPoint); |
| |
| // Queries the per-pixel HW sample locations for the given render target, and then finds or |
| // assigns a key that uniquely identifies the sample pattern. The actual sample locations can be |
| // retrieved with retrieveSampleLocations(). |
| int findOrAssignSamplePatternKey(GrRenderTarget*); |
| |
| // Retrieves the per-pixel HW sample locations for the given sample pattern key, and, as a |
| // by-product, the actual number of samples in use. (This may differ from the number of samples |
| // requested by the render target.) Sample locations are returned as 0..1 offsets relative to |
| // the top-left corner of the pixel. |
| const SkTArray<SkPoint>& retrieveSampleLocations(int samplePatternKey) const { |
| return fSamplePatternDictionary.retrieveSampleLocations(samplePatternKey); |
| } |
| |
| // Returns a GrOpsRenderPass which GrOpsTasks send draw commands to instead of directly |
| // to the Gpu object. The 'bounds' rect is the content rect of the renderTarget. |
| virtual GrOpsRenderPass* getOpsRenderPass( |
| GrRenderTarget* renderTarget, GrSurfaceOrigin, const SkIRect& bounds, |
| const GrOpsRenderPass::LoadAndStoreInfo&, |
| const GrOpsRenderPass::StencilLoadAndStoreInfo&, |
| const SkTArray<GrTextureProxy*, true>& sampledProxies) = 0; |
| |
| // Called by GrDrawingManager when flushing. |
| // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also |
| // insert any numSemaphore semaphores on the gpu and set the backendSemaphores to match the |
| // inserted semaphores. |
| GrSemaphoresSubmitted finishFlush(GrSurfaceProxy*[], int n, |
| SkSurface::BackendSurfaceAccess access, const GrFlushInfo&, |
| const GrPrepareForExternalIORequests&); |
| |
| virtual void submit(GrOpsRenderPass*) = 0; |
| |
| virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0; |
| virtual bool waitFence(GrFence, uint64_t timeout = 1000) = 0; |
| virtual void deleteFence(GrFence) const = 0; |
| |
| virtual sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned = true) = 0; |
| virtual sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore, |
| GrResourceProvider::SemaphoreWrapType wrapType, |
| GrWrapOwnership ownership) = 0; |
| virtual void insertSemaphore(sk_sp<GrSemaphore> semaphore) = 0; |
| virtual void waitSemaphore(sk_sp<GrSemaphore> semaphore) = 0; |
| |
| virtual void checkFinishProcs() = 0; |
| |
| /** |
| * Put this texture in a safe and known state for use across multiple GrContexts. Depending on |
| * the backend, this may return a GrSemaphore. If so, other contexts should wait on that |
| * semaphore before using this texture. |
| */ |
| virtual sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) = 0; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // Debugging and Stats |
| |
| class Stats { |
| public: |
| #if GR_GPU_STATS |
| Stats() = default; |
| |
| void reset() { *this = {}; } |
| |
| int renderTargetBinds() const { return fRenderTargetBinds; } |
| void incRenderTargetBinds() { fRenderTargetBinds++; } |
| |
| int shaderCompilations() const { return fShaderCompilations; } |
| void incShaderCompilations() { fShaderCompilations++; } |
| |
| int textureCreates() const { return fTextureCreates; } |
| void incTextureCreates() { fTextureCreates++; } |
| |
| int textureUploads() const { return fTextureUploads; } |
| void incTextureUploads() { fTextureUploads++; } |
| |
| int transfersToTexture() const { return fTransfersToTexture; } |
| void incTransfersToTexture() { fTransfersToTexture++; } |
| |
| int transfersFromSurface() const { return fTransfersFromSurface; } |
| void incTransfersFromSurface() { fTransfersFromSurface++; } |
| |
| int stencilAttachmentCreates() const { return fStencilAttachmentCreates; } |
| void incStencilAttachmentCreates() { fStencilAttachmentCreates++; } |
| |
| int numDraws() const { return fNumDraws; } |
| void incNumDraws() { fNumDraws++; } |
| |
| int numFailedDraws() const { return fNumFailedDraws; } |
| void incNumFailedDraws() { ++fNumFailedDraws; } |
| |
| int numFinishFlushes() const { return fNumFinishFlushes; } |
| void incNumFinishFlushes() { ++fNumFinishFlushes; } |
| |
| int numScratchTexturesReused() const { return fNumScratchTexturesReused; } |
| void incNumScratchTexturesReused() { ++fNumScratchTexturesReused; } |
| |
| #if GR_TEST_UTILS |
| void dump(SkString*); |
| void dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values); |
| #endif |
| private: |
| int fRenderTargetBinds = 0; |
| int fShaderCompilations = 0; |
| int fTextureCreates = 0; |
| int fTextureUploads = 0; |
| int fTransfersToTexture = 0; |
| int fTransfersFromSurface = 0; |
| int fStencilAttachmentCreates = 0; |
| int fNumDraws = 0; |
| int fNumFailedDraws = 0; |
| int fNumFinishFlushes = 0; |
| int fNumScratchTexturesReused = 0; |
| #else |
| |
| #if GR_TEST_UTILS |
| void dump(SkString*) {} |
| void dumpKeyValuePairs(SkTArray<SkString>*, SkTArray<double>*) {} |
| #endif |
| void incRenderTargetBinds() {} |
| void incShaderCompilations() {} |
| void incTextureCreates() {} |
| void incTextureUploads() {} |
| void incTransfersToTexture() {} |
| void incStencilAttachmentCreates() {} |
| void incNumDraws() {} |
| void incNumFailedDraws() {} |
| void incNumFinishFlushes() {} |
| #endif |
| }; |
| |
| Stats* stats() { return &fStats; } |
| void dumpJSON(SkJSONWriter*) const; |
| |
| /** |
| * Creates a texture directly in the backend API without wrapping it in a GrTexture. |
| * Must be matched with a call to deleteBackendTexture(). |
| * |
| * If srcData is provided it will be used to initialize the texture. If srcData is |
| * not provided but a color is then it is used to initialize the texture. If neither |
| * srcData nor a color is provided then the texture is left uninitialized. |
| * |
| * If srcData is provided and mipMapped is kYes then data for all the miplevels must be |
| * provided (or the method will fail). If only a color is provided and mipMapped is kYes |
| * then all the mip levels will be allocated and initialized to the color. If neither |
| * srcData nor a color is provided but mipMapped is kYes then the mip levels will be allocated |
| * but left uninitialized. |
| * |
| * Note: if more than one pixmap is provided (i.e., for mipmap levels) they must all share |
| * the same SkColorType. |
| */ |
| GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&, |
| GrMipMapped, GrRenderable, |
| const SkPixmap srcData[], int numMipLevels, |
| const SkColor4f* color, GrProtected isProtected); |
| |
| /** |
| * Frees a texture created by createBackendTexture(). If ownership of the backend |
| * texture has been transferred to a GrContext using adopt semantics this should not be called. |
| */ |
| virtual void deleteBackendTexture(const GrBackendTexture&) = 0; |
| |
| virtual bool precompileShader(const SkData& key, const SkData& data) { return false; } |
| |
| #if GR_TEST_UTILS |
| /** Check a handle represents an actual texture in the backend API that has not been freed. */ |
| virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0; |
| |
| virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, |
| GrColorType) = 0; |
| |
| virtual void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) = 0; |
| |
| // This is only to be used in GL-specific tests. |
| virtual const GrGLContext* glContextForTesting() const { return nullptr; } |
| |
| // This is only to be used by testing code |
| virtual void resetShaderCacheForTesting() const {} |
| |
| /** |
| * Flushes all work to the gpu and forces the GPU to wait until all the gpu work has completed. |
| * This is for testing purposes only. |
| */ |
| virtual void testingOnly_flushGpuAndSync() = 0; |
| |
| /** |
| * Inserted as a pair around a block of code to do a GPU frame capture. |
| * Currently only works with the Metal backend. |
| */ |
| virtual void testingOnly_startCapture() {} |
| virtual void testingOnly_endCapture() {} |
| #endif |
| |
| // width and height may be larger than rt (if underlying API allows it). |
| // Returns nullptr if compatible sb could not be created, otherwise the caller owns the ref on |
| // the GrStencilAttachment. |
| virtual GrStencilAttachment* createStencilAttachmentForRenderTarget( |
| const GrRenderTarget*, int width, int height, int numStencilSamples) = 0; |
| |
| // Determines whether a texture will need to be rescaled in order to be used with the |
| // GrSamplerState. |
| static bool IsACopyNeededForRepeatWrapMode(const GrCaps*, GrTextureProxy* texProxy, |
| int width, int height, |
| GrSamplerState::Filter, |
| GrTextureProducer::CopyParams*, |
| SkScalar scaleAdjust[2]); |
| |
| // Determines whether a texture will need to be copied because the draw requires mips but the |
| // texutre doesn't have any. This call should be only checked if IsACopyNeededForTextureParams |
| // fails. If the previous call succeeds, then a copy should be done using those params and the |
| // mip mapping requirements will be handled there. |
| static bool IsACopyNeededForMips(const GrCaps* caps, const GrTextureProxy* texProxy, |
| GrSamplerState::Filter filter, |
| GrTextureProducer::CopyParams* copyParams); |
| |
| void handleDirtyContext() { |
| if (fResetBits) { |
| this->resetContext(); |
| } |
| } |
| |
| /** |
| * Returns a key that represents the sampler that will be created for the passed in parameters. |
| * Currently this key is only used when we are building a vulkan pipeline with immutable |
| * samplers. In that case, we need our cache key to also contain this key. |
| * |
| * A return value of 0 indicates that the program/pipeline we are creating is not affected by |
| * the sampler. |
| */ |
| virtual uint32_t getExtraSamplerKeyForProgram(const GrSamplerState&, const GrBackendFormat&) { |
| return 0; |
| } |
| |
| virtual void storeVkPipelineCacheData() {} |
| |
| protected: |
| static bool MipMapsAreCorrect(int baseWidth, int baseHeight, GrMipMapped, |
| const SkPixmap srcData[], int numMipLevels); |
| |
| // Handles cases where a surface will be updated without a call to flushRenderTarget. |
| void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds, |
| uint32_t mipLevels = 1) const; |
| |
| Stats fStats; |
| std::unique_ptr<GrPathRendering> fPathRendering; |
| // Subclass must initialize this in its constructor. |
| sk_sp<const GrCaps> fCaps; |
| |
| private: |
| virtual GrBackendTexture onCreateBackendTexture(int w, int h, const GrBackendFormat&, |
| GrMipMapped, GrRenderable, |
| const SkPixmap srcData[], int numMipLevels, |
| const SkColor4f* color, GrProtected) = 0; |
| |
| // called when the 3D context state is unknown. Subclass should emit any |
| // assumed 3D context state and dirty any state cache. |
| virtual void onResetContext(uint32_t resetBits) = 0; |
| |
| // Implementation of resetTextureBindings. |
| virtual void onResetTextureBindings() {} |
| |
| // Queries the effective number of samples in use by the hardware for the given render target, |
| // and queries the individual sample locations. |
| virtual void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) = 0; |
| |
| // Called before certain draws in order to guarantee coherent results from dst reads. |
| virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0; |
| |
| // overridden by backend-specific derived class to create objects. |
| // Texture size, renderablility, format support, sample count will have already been validated |
| // in base class before onCreateTexture is called. |
| // If the ith bit is set in levelClearMask then the ith MIP level should be cleared. |
| virtual sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, |
| const GrBackendFormat&, |
| GrRenderable, |
| int renderTargetSampleCnt, |
| SkBudgeted, |
| GrProtected, |
| int mipLevelCoont, |
| uint32_t levelClearMask) = 0; |
| virtual sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, |
| const GrBackendFormat&, |
| SkImage::CompressionType, SkBudgeted, |
| const void* data) = 0; |
| virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, |
| GrWrapOwnership, GrWrapCacheable, GrIOType) = 0; |
| virtual sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt, |
| GrColorType, GrWrapOwnership, |
| GrWrapCacheable) = 0; |
| virtual sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&, |
| GrColorType) = 0; |
| virtual sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&, |
| int sampleCnt, |
| GrColorType) = 0; |
| virtual sk_sp<GrRenderTarget> onWrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, |
| const GrVkDrawableInfo&); |
| |
| virtual sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, |
| GrAccessPattern, const void* data) = 0; |
| |
| // overridden by backend-specific derived class to perform the surface read |
| virtual bool onReadPixels(GrSurface*, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType dstColorType, void* buffer, |
| size_t rowBytes) = 0; |
| |
| // overridden by backend-specific derived class to perform the surface write |
| virtual bool onWritePixels(GrSurface*, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType srcColorType, |
| const GrMipLevel texels[], int mipLevelCount, |
| bool prepForTexSampling) = 0; |
| |
| // overridden by backend-specific derived class to perform the texture transfer |
| virtual bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height, |
| GrColorType textiueColorType, GrColorType bufferColorType, |
| GrGpuBuffer* transferBuffer, size_t offset, |
| size_t rowBytes) = 0; |
| // overridden by backend-specific derived class to perform the surface transfer |
| virtual bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height, |
| GrColorType surfaceColorType, GrColorType bufferColorType, |
| GrGpuBuffer* transferBuffer, size_t offset) = 0; |
| |
| // overridden by backend-specific derived class to perform the resolve |
| virtual void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect, |
| GrSurfaceOrigin resolveOrigin, ForExternalIO) = 0; |
| |
| // overridden by backend specific derived class to perform mip map level regeneration. |
| virtual bool onRegenerateMipMapLevels(GrTexture*) = 0; |
| |
| // overridden by backend specific derived class to perform the copy surface |
| virtual bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, |
| const SkIPoint& dstPoint) = 0; |
| |
| virtual void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access, |
| const GrFlushInfo&, const GrPrepareForExternalIORequests&) = 0; |
| |
| #ifdef SK_ENABLE_DUMP_GPU |
| virtual void onDumpJSON(SkJSONWriter*) const {} |
| #endif |
| |
| sk_sp<GrTexture> createTextureCommon(const GrSurfaceDesc& desc, |
| const GrBackendFormat& format, |
| GrRenderable renderable, |
| int renderTargetSampleCnt, |
| SkBudgeted budgeted, |
| GrProtected isProtected, |
| int mipLevelCnt, |
| uint32_t levelClearMask); |
| |
| void resetContext() { |
| this->onResetContext(fResetBits); |
| fResetBits = 0; |
| } |
| |
| uint32_t fResetBits; |
| // The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu. |
| GrContext* fContext; |
| GrSamplePatternDictionary fSamplePatternDictionary; |
| |
| friend class GrPathRendering; |
| typedef SkRefCnt INHERITED; |
| }; |
| |
| #endif |