aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu
diff options
context:
space:
mode:
authorGravatar csmartdalton <csmartdalton@google.com>2016-07-13 10:16:32 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-13 10:16:32 -0700
commit485a12003ab48b54965d6f7172f3183358919d8e (patch)
tree090548d2a98d35849dfbedeafa10020507f3194c /include/gpu
parent6c3ada96ab2326f2119e1e9f44fbc8b0aeadbae8 (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.h67
-rw-r--r--include/gpu/GrCaps.h2
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;