diff options
author | 2016-07-13 10:16:32 -0700 | |
---|---|---|
committer | 2016-07-13 10:16:32 -0700 | |
commit | 485a12003ab48b54965d6f7172f3183358919d8e (patch) | |
tree | 090548d2a98d35849dfbedeafa10020507f3194c /include/gpu | |
parent | 6c3ada96ab2326f2119e1e9f44fbc8b0aeadbae8 (diff) |
Add resource provider flag to avoid client-side buffers
On some platforms, a newly-created buffer was liable to be CPU backed.
This would break code that expected a VBO (aka instanced rendering).
This change adds an optional flag to GrResourceProvider that requires
a buffer to be created in GPU memory.
It also moves the CPU backing logic into Gr land in order to properly
cache real VBOs on platforms that prefer client-side buffers.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2143333002
Review-Url: https://codereview.chromium.org/2143333002
Diffstat (limited to 'include/gpu')
-rw-r--r-- | include/gpu/GrBuffer.h | 67 | ||||
-rw-r--r-- | include/gpu/GrCaps.h | 2 |
2 files changed, 32 insertions, 37 deletions
diff --git a/include/gpu/GrBuffer.h b/include/gpu/GrBuffer.h index 829596e734..b2201a140f 100644 --- a/include/gpu/GrBuffer.h +++ b/include/gpu/GrBuffer.h @@ -15,30 +15,26 @@ class GrGpu; class GrBuffer : public GrGpuResource { public: /** - * Computes a scratch key for a buffer with a "dynamic" access pattern. (Buffers with "static" - * and "stream" access patterns are disqualified by nature from being cached and reused.) + * Creates a client-side buffer. */ - static void ComputeScratchKeyForDynamicBuffer(size_t size, GrBufferType intendedType, - GrScratchKey* key) { - static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); - GrScratchKey::Builder builder(key, kType, 1 + (sizeof(size_t) + 3) / 4); - // TODO: There's not always reason to cache a buffer by type. In some (all?) APIs it's just - // a chunk of memory we can use/reuse for any type of data. We really only need to - // differentiate between the "read" types (e.g. kGpuToCpu_BufferType) and "draw" types. - builder[0] = intendedType; - builder[1] = (uint32_t)size; - if (sizeof(size_t) > 4) { - builder[2] = (uint32_t)((uint64_t)size >> 32); - } - } + static SK_WARN_UNUSED_RESULT GrBuffer* CreateCPUBacked(GrGpu*, size_t sizeInBytes, GrBufferType, + const void* data = nullptr); + + /** + * Computes a scratch key for a GPU-side buffer with a "dynamic" access pattern. (Buffers with + * "static" and "stream" patterns are disqualified by nature from being cached and reused.) + */ + static void ComputeScratchKeyForDynamicVBO(size_t size, GrBufferType, GrScratchKey*); GrAccessPattern accessPattern() const { return fAccessPattern; } + size_t sizeInBytes() const { return fSizeInBytes; } /** * Returns true if the buffer is a wrapper around a CPU array. If true it * indicates that map will always succeed and will be free. */ - bool isCPUBacked() const { return fCPUBacked; } + bool isCPUBacked() const { return SkToBool(fCPUData); } + size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); } /** * Maps the buffer to be written by the CPU. @@ -103,40 +99,37 @@ public: */ bool updateData(const void* src, size_t srcSizeInBytes) { SkASSERT(!this->isMapped()); - SkASSERT(srcSizeInBytes <= fGpuMemorySize); + SkASSERT(srcSizeInBytes <= fSizeInBytes); return this->onUpdateData(src, srcSizeInBytes); } -protected: - GrBuffer(GrGpu* gpu, size_t gpuMemorySize, GrBufferType intendedType, - GrAccessPattern accessPattern, bool cpuBacked) - : INHERITED(gpu), - fMapPtr(nullptr), - fGpuMemorySize(gpuMemorySize), // TODO: Zero for cpu backed buffers? - fAccessPattern(accessPattern), - fCPUBacked(cpuBacked), - fIntendedType(intendedType) { + ~GrBuffer() override { + sk_free(fCPUData); } - void computeScratchKey(GrScratchKey* key) const override { - if (!fCPUBacked && SkIsPow2(fGpuMemorySize) && kDynamic_GrAccessPattern == fAccessPattern) { - ComputeScratchKeyForDynamicBuffer(fGpuMemorySize, fIntendedType, key); - } - } +protected: + GrBuffer(GrGpu*, size_t sizeInBytes, GrBufferType, GrAccessPattern); void* fMapPtr; private: - size_t onGpuMemorySize() const override { return fGpuMemorySize; } + /** + * Internal constructor to make a CPU-backed buffer. + */ + GrBuffer(GrGpu*, size_t sizeInBytes, GrBufferType, void* cpuData); - virtual void onMap() = 0; - virtual void onUnmap() = 0; - virtual bool onUpdateData(const void* src, size_t srcSizeInBytes) = 0; + virtual void onMap() { SkASSERT(this->isCPUBacked()); fMapPtr = fCPUData; } + virtual void onUnmap() { SkASSERT(this->isCPUBacked()); } + virtual bool onUpdateData(const void* src, size_t srcSizeInBytes); - size_t fGpuMemorySize; + size_t onGpuMemorySize() const override { return fSizeInBytes; } // TODO: zero for cpu backed? + void computeScratchKey(GrScratchKey* key) const override; + + size_t fSizeInBytes; GrAccessPattern fAccessPattern; - bool fCPUBacked; + void* fCPUData; GrBufferType fIntendedType; + typedef GrGpuResource INHERITED; }; diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index 35e2c2ca30..5086d79be9 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -160,6 +160,7 @@ public: bool sampleLocationsSupport() const { return fSampleLocationsSupport; } bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } bool usesMixedSamples() const { return fUsesMixedSamples; } + bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; } bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; } bool useDrawInsteadOfPartialRenderTargetWrite() const { @@ -297,6 +298,7 @@ protected: bool fSampleLocationsSupport : 1; bool fMultisampleDisableSupport : 1; bool fUsesMixedSamples : 1; + bool fPreferClientSideDynamicBuffers : 1; bool fSupportsInstancedDraws : 1; bool fFullClearIsFree : 1; bool fMustClearUploadedBufferData : 1; |