Index: src/gpu/gl/GrGLCreateNullInterface.cpp |
diff --git a/src/gpu/gl/GrGLCreateNullInterface.cpp b/src/gpu/gl/GrGLCreateNullInterface.cpp |
index a511a1832fbd49574e71173ba6e456919ea4b693..efdea2b47fb8eecacee859318359cbd64fe7640b 100644 |
--- a/src/gpu/gl/GrGLCreateNullInterface.cpp |
+++ b/src/gpu/gl/GrGLCreateNullInterface.cpp |
@@ -6,97 +6,19 @@ |
*/ |
-#include "GrNonAtomicRef.h" |
#include "gl/GrGLInterface.h" |
#include "GrGLTestInterface.h" |
#include "SkMutex.h" |
#include "SkTDArray.h" |
-#include <type_traits> |
// added to suppress 'no previous prototype' warning and because this code is duplicated in |
// SkNullGLContext.cpp |
namespace { |
-class GLObject : public GrNonAtomicRef<GLObject> { |
+class BufferObj { |
public: |
- GLObject(GrGLuint id) : fID(id) {} |
- GrGLuint id() const { return fID; } |
- |
-private: |
- GrGLuint fID; |
-}; |
- |
-// This class maintains a sparsely populated array of object pointers. |
-template<typename T> class TGLObjectManager { |
- static_assert(std::is_convertible<T*, GLObject*>::value, "T must be a subclass of GLObject"); |
- |
-public: |
- TGLObjectManager() : fFreeListHead(kFreeListEnd) { |
- *fGLObjects.append() = nullptr; // 0 is not a valid GL object id. |
- } |
- |
- ~TGLObjectManager() { |
- // nullptr out the entries that are really free list links rather than ptrs before deleting. |
- intptr_t curr = fFreeListHead; |
- while (kFreeListEnd != curr) { |
- intptr_t next = reinterpret_cast<intptr_t>(fGLObjects[SkToS32(curr)]); |
- fGLObjects[SkToS32(curr)] = nullptr; |
- curr = next; |
- } |
- |
- fGLObjects.safeUnrefAll(); |
- } |
- |
- T* lookUp(GrGLuint id) { |
- T* object = fGLObjects[id]; |
- SkASSERT(object && object->id() == id); |
- return object; |
- } |
- |
- T* create() { |
- GrGLuint id; |
- T* object; |
- |
- if (kFreeListEnd == fFreeListHead) { |
- // no free slots - create a new one |
- id = fGLObjects.count(); |
- object = new T(id); |
- *fGLObjects.append() = object; |
- } else { |
- // grab the head of the free list and advance the head to the next free slot. |
- id = static_cast<GrGLuint>(fFreeListHead); |
- fFreeListHead = reinterpret_cast<intptr_t>(fGLObjects[id]); |
- |
- object = new T(id); |
- fGLObjects[id] = object; |
- } |
- |
- return object; |
- } |
- |
- void free(T* object) { |
- SkASSERT(object); |
- SkASSERT(fGLObjects.count() > 0); |
- |
- GrGLuint id = object->id(); |
- object->unref(); |
- |
- fGLObjects[id] = reinterpret_cast<T*>(fFreeListHead); |
- fFreeListHead = id; |
- } |
- |
-private: |
- static const intptr_t kFreeListEnd = -1; |
- // Index of the first entry of fGLObjects in the free list. Free slots in fGLObjects are indices |
- // to the next free slot. The last free slot has a value of kFreeListEnd. |
- intptr_t fFreeListHead; |
- SkTDArray<T*> fGLObjects; |
-}; |
- |
-class Buffer : public GLObject { |
-public: |
- Buffer(GrGLuint id) : INHERITED(id), fDataPtr(nullptr), fSize(0), fMapped(false) {} |
- ~Buffer() { delete[] fDataPtr; } |
+ BufferObj(GrGLuint id) : fID(id), fDataPtr(nullptr), fSize(0), fMapped(false) {} |
+ ~BufferObj() { delete[] fDataPtr; } |
void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) { |
if (fDataPtr) { |
@@ -108,6 +30,7 @@ |
fDataPtr = new char[size]; |
} |
+ GrGLuint id() const { return fID; } |
GrGLchar* dataPtr() { return fDataPtr; } |
GrGLsizeiptr size() const { return fSize; } |
@@ -115,107 +38,82 @@ |
bool mapped() const { return fMapped; } |
private: |
+ GrGLuint fID; |
GrGLchar* fDataPtr; |
GrGLsizeiptr fSize; // size in bytes |
bool fMapped; |
- |
- typedef GLObject INHERITED; |
}; |
-class FramebufferAttachment : public GLObject { |
+// This class maintains a sparsely populated array of buffer pointers. |
+class BufferManager { |
public: |
- FramebufferAttachment(int id) : INHERITED(id), fNumSamples(1) {} |
- int numSamples() const { return fNumSamples; } |
- |
-protected: |
- int fNumSamples; |
- |
- typedef GLObject INHERITED; |
-}; |
- |
-class Renderbuffer : public FramebufferAttachment { |
-public: |
- Renderbuffer(int id) : INHERITED(id) {} |
- void setNumSamples(int numSamples) { fNumSamples = numSamples; } |
+ BufferManager() : fFreeListHead(kFreeListEnd) { |
+ *fBuffers.append() = nullptr; // 0 is not a valid GL buffer id. |
+ } |
+ |
+ ~BufferManager() { |
+ // nullptr out the entries that are really free list links rather than ptrs before deleting. |
+ intptr_t curr = fFreeListHead; |
+ while (kFreeListEnd != curr) { |
+ intptr_t next = reinterpret_cast<intptr_t>(fBuffers[SkToS32(curr)]); |
+ fBuffers[SkToS32(curr)] = nullptr; |
+ curr = next; |
+ } |
+ |
+ fBuffers.deleteAll(); |
+ } |
+ |
+ BufferObj* lookUp(GrGLuint id) { |
+ BufferObj* buffer = fBuffers[id]; |
+ SkASSERT(buffer && buffer->id() == id); |
+ return buffer; |
+ } |
+ |
+ BufferObj* create() { |
+ GrGLuint id; |
+ BufferObj* buffer; |
+ |
+ if (kFreeListEnd == fFreeListHead) { |
+ // no free slots - create a new one |
+ id = fBuffers.count(); |
+ buffer = new BufferObj(id); |
+ *fBuffers.append() = buffer; |
+ } else { |
+ // grab the head of the free list and advance the head to the next free slot. |
+ id = static_cast<GrGLuint>(fFreeListHead); |
+ fFreeListHead = reinterpret_cast<intptr_t>(fBuffers[id]); |
+ |
+ buffer = new BufferObj(id); |
+ fBuffers[id] = buffer; |
+ } |
+ |
+ return buffer; |
+ } |
+ |
+ void free(BufferObj* buffer) { |
+ SkASSERT(buffer); |
+ SkASSERT(fBuffers.count() > 0); |
+ |
+ GrGLuint id = buffer->id(); |
+ delete buffer; |
+ |
+ fBuffers[id] = reinterpret_cast<BufferObj*>(fFreeListHead); |
+ fFreeListHead = id; |
+ } |
private: |
- typedef FramebufferAttachment INHERITED; |
-}; |
- |
-class Texture : public FramebufferAttachment { |
-public: |
- Texture(int id) : INHERITED(id) {} |
- |
-private: |
- typedef FramebufferAttachment INHERITED; |
-}; |
- |
-class Framebuffer : public GLObject { |
-public: |
- Framebuffer(int id) : INHERITED(id) {} |
- |
- void setAttachment(GrGLenum attachmentPoint, const FramebufferAttachment* attachment) { |
- switch (attachmentPoint) { |
- default: |
- SK_ABORT("Invalid framebuffer attachment."); |
- break; |
- case GR_GL_STENCIL_ATTACHMENT: |
- fAttachments[(int)AttachmentPoint::kStencil].reset(SkRef(attachment)); |
- break; |
- case GR_GL_DEPTH_ATTACHMENT: |
- fAttachments[(int)AttachmentPoint::kDepth].reset(SkRef(attachment)); |
- break; |
- case GR_GL_COLOR_ATTACHMENT0: |
- fAttachments[(int)AttachmentPoint::kColor].reset(SkRef(attachment)); |
- break; |
- } |
- } |
- |
- void notifyAttachmentDeleteWhileBound(const FramebufferAttachment* deleted) { |
- for (auto& attachment : fAttachments) { |
- if (attachment == deleted) { |
- attachment.reset(nullptr); |
- } |
- } |
- } |
- |
- int numSamples() const { |
- int numSamples = 0; |
- for (auto& attachment : fAttachments) { |
- if (!attachment) { |
- continue; |
- } |
- if (numSamples) { |
- GrAlwaysAssert(attachment->numSamples() == numSamples); |
- continue; |
- } |
- numSamples = attachment->numSamples(); |
- } |
- GrAlwaysAssert(numSamples); |
- return numSamples; |
- } |
- |
-private: |
- enum AttachmentPoint { |
- kStencil, |
- kDepth, |
- kColor |
- }; |
- constexpr int static kNumAttachmentPoints = 1 + (int)AttachmentPoint::kColor; |
- |
- SkAutoTUnref<const FramebufferAttachment> fAttachments[kNumAttachmentPoints]; |
- |
- typedef GLObject INHERITED; |
+ static const intptr_t kFreeListEnd = -1; |
+ // Index of the first entry of fBuffers in the free list. Free slots in fBuffers are indices to |
+ // the next free slot. The last free slot has a value of kFreeListEnd. |
+ intptr_t fFreeListHead; |
+ SkTDArray<BufferObj*> fBuffers; |
}; |
/** Null interface implementation */ |
class NullInterface : public GrGLTestInterface { |
public: |
NullInterface(bool enableNVPR) |
- : fCurrDrawFramebuffer(0) |
- , fCurrReadFramebuffer(0) |
- , fCurrRenderbuffer(0) |
- , fCurrProgramID(0) |
+ : fCurrProgramID(0) |
, fCurrShaderID(0) |
, fCurrGenericID(0) |
, fCurrUniformLocation(0) |
@@ -242,7 +140,7 @@ |
GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { |
for (int i = 0; i < n; ++i) { |
- Buffer* buffer = fBufferManager.create(); |
+ BufferObj* buffer = fBufferManager.create(); |
ids[i] = buffer->id(); |
} |
} |
@@ -251,7 +149,7 @@ |
GrGLenum usage) override { |
GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
if (id > 0) { |
- Buffer* buffer = fBufferManager.lookUp(id); |
+ BufferObj* buffer = fBufferManager.lookUp(id); |
buffer->allocate(size, (const GrGLchar*) data); |
} |
} |
@@ -286,193 +184,24 @@ |
// Then actually "delete" the buffers. |
for (int i = 0; i < n; ++i) { |
if (ids[i] > 0) { |
- Buffer* buffer = fBufferManager.lookUp(ids[i]); |
+ BufferObj* buffer = fBufferManager.lookUp(ids[i]); |
fBufferManager.free(buffer); |
} |
} |
} |
GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override { |
- for (int i = 0; i < n; ++i) { |
- Framebuffer* framebuffer = fFramebufferManager.create(); |
- framebuffers[i] = framebuffer->id(); |
- } |
- } |
- |
- GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint framebuffer) override { |
- SkASSERT(GR_GL_FRAMEBUFFER == target || GR_GL_DRAW_FRAMEBUFFER == target || |
- GR_GL_READ_FRAMEBUFFER == target); |
- if (GR_GL_READ_FRAMEBUFFER != target) { |
- fCurrDrawFramebuffer = framebuffer; |
- } |
- if (GR_GL_DRAW_FRAMEBUFFER != target) { |
- fCurrReadFramebuffer = framebuffer; |
- } |
- } |
- |
- GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint* ids) override { |
- for (int i = 0; i < n; ++i) { |
- if (ids[i] == fCurrDrawFramebuffer) { |
- fCurrDrawFramebuffer = 0; |
- } |
- if (ids[i] == fCurrReadFramebuffer) { |
- fCurrReadFramebuffer = 0; |
- } |
- |
- if (ids[i] > 0) { |
- Framebuffer* framebuffer = fFramebufferManager.lookUp(ids[i]); |
- fFramebufferManager.free(framebuffer); |
- } |
- } |
+ this->genGenericIds(n, framebuffers); |
} |
GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); } |
GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override { |
- for (int i = 0; i < n; ++i) { |
- Renderbuffer* renderbuffer = fRenderbufferManager.create(); |
- renderbuffers[i] = renderbuffer->id(); |
- } |
- } |
- |
- GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) override { |
- SkASSERT(GR_GL_RENDERBUFFER == target); |
- fCurrRenderbuffer = renderbuffer; |
- } |
- |
- GrGLvoid deleteRenderbuffers(GrGLsizei n, const GrGLuint* ids) override { |
- for (int i = 0; i < n; ++i) { |
- if (ids[i] <= 0) { |
- continue; |
- } |
- if (ids[i] == fCurrRenderbuffer) { |
- fCurrRenderbuffer = 0; |
- } |
- Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(ids[i]); |
- |
- if (fCurrDrawFramebuffer) { |
- Framebuffer* drawFramebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer); |
- drawFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer); |
- } |
- if (fCurrReadFramebuffer) { |
- Framebuffer* readFramebuffer = fFramebufferManager.lookUp(fCurrReadFramebuffer); |
- readFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer); |
- } |
- |
- fRenderbufferManager.free(renderbuffer); |
- } |
- } |
- |
- GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, |
- GrGLsizei height) override { |
- GrAlwaysAssert(GR_GL_RENDERBUFFER == target); |
- GrAlwaysAssert(fCurrRenderbuffer); |
- Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer); |
- renderbuffer->setNumSamples(1); |
- } |
- |
- GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, |
- GrGLenum internalformat, GrGLsizei width, |
- GrGLsizei height) override { |
- GrAlwaysAssert(GR_GL_RENDERBUFFER == target); |
- GrAlwaysAssert(samples > 0); |
- GrAlwaysAssert(fCurrRenderbuffer); |
- Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer); |
- renderbuffer->setNumSamples(samples); |
- } |
- |
- GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat, |
- GrGLsizei width, GrGLsizei height) override { |
- SK_ABORT("Not implemented"); |
- } |
- |
- GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples, |
- GrGLenum GrGLinternalformat, GrGLsizei width, |
- GrGLsizei height) override { |
- SK_ABORT("Not implemented"); |
- } |
- |
- GrGLvoid framebufferRenderbuffer(GrGLenum target, GrGLenum attachment, |
- GrGLenum renderbuffertarget, |
- GrGLuint renderBufferID) override { |
- GrGLuint id = this->getBoundFramebufferID(target); |
- GrAlwaysAssert(id); |
- Framebuffer* framebuffer = fFramebufferManager.lookUp(id); |
- |
- GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); |
- GrAlwaysAssert(fCurrRenderbuffer); |
- Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer); |
- |
- framebuffer->setAttachment(attachment, renderbuffer); |
- } |
- |
- GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment, |
- GrGLenum renderbuffertarget, |
- GrGLuint renderbuffer) override { |
- SK_ABORT("Not implemented"); |
+ this->genGenericIds(n, renderbuffers); |
} |
GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override { |
- for (int i = 0; i < n; ++i) { |
- Texture* texture = fTextureManager.create(); |
- textures[i] = texture->id(); |
- } |
- } |
- |
- GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* ids) override { |
- for (int i = 0; i < n; ++i) { |
- if (ids[i] <= 0) { |
- continue; |
- } |
- Texture* texture = fTextureManager.lookUp(ids[i]); |
- |
- if (fCurrDrawFramebuffer) { |
- Framebuffer* drawFramebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer); |
- drawFramebuffer->notifyAttachmentDeleteWhileBound(texture); |
- } |
- if (fCurrReadFramebuffer) { |
- Framebuffer* readFramebuffer = fFramebufferManager.lookUp(fCurrReadFramebuffer); |
- readFramebuffer->notifyAttachmentDeleteWhileBound(texture); |
- } |
- |
- fTextureManager.free(texture); |
- } |
- } |
- |
- GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, |
- GrGLuint textureID, GrGLint level) override { |
- GrGLuint id = this->getBoundFramebufferID(target); |
- GrAlwaysAssert(id); |
- Framebuffer* framebuffer = fFramebufferManager.lookUp(id); |
- |
- GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); |
- Texture* texture = fTextureManager.lookUp(textureID); |
- |
- framebuffer->setAttachment(attachment, texture); |
- } |
- |
- GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment, |
- GrGLenum textarget, GrGLuint texture, GrGLint level, |
- GrGLsizei samples) override { |
- SK_ABORT("Not implemented"); |
- } |
- |
- GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment, |
- GrGLenum textarget, GrGLuint texture, |
- GrGLint level) override { |
- SK_ABORT("Not implemented"); |
- } |
- |
- GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment, |
- GrGLenum textarget, GrGLuint texture, |
- GrGLint level) override { |
- SK_ABORT("Not implemented"); |
- } |
- |
- GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment, |
- GrGLenum textarget, GrGLuint texture, GrGLint level, |
- GrGLint zoffset) override { |
- SK_ABORT("Not implemented"); |
+ this->genGenericIds(n, textures); |
} |
GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override { |
@@ -491,12 +220,9 @@ |
case GR_GL_STENCIL_BITS: |
*params = 8; |
break; |
- case GR_GL_SAMPLES: { |
- GrAlwaysAssert(fCurrDrawFramebuffer); |
- Framebuffer* framebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer); |
- *params = framebuffer->numSamples(); |
- break; |
- } |
+ case GR_GL_SAMPLES: |
+ *params = 1; |
+ break; |
case GR_GL_FRAMEBUFFER_BINDING: |
*params = 0; |
break; |
@@ -650,7 +376,7 @@ |
GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
if (id > 0) { |
// We just ignore the offset and length here. |
- Buffer* buffer = fBufferManager.lookUp(id); |
+ BufferObj* buffer = fBufferManager.lookUp(id); |
SkASSERT(!buffer->mapped()); |
buffer->setMapped(true); |
return buffer->dataPtr(); |
@@ -661,7 +387,7 @@ |
GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { |
GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
if (id > 0) { |
- Buffer* buffer = fBufferManager.lookUp(id); |
+ BufferObj* buffer = fBufferManager.lookUp(id); |
SkASSERT(!buffer->mapped()); |
buffer->setMapped(true); |
return buffer->dataPtr(); |
@@ -674,7 +400,7 @@ |
GrGLboolean unmapBuffer(GrGLenum target) override { |
GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
if (id > 0) { |
- Buffer* buffer = fBufferManager.lookUp(id); |
+ BufferObj* buffer = fBufferManager.lookUp(id); |
SkASSERT(buffer->mapped()); |
buffer->setMapped(false); |
return GR_GL_TRUE; |
@@ -690,7 +416,7 @@ |
*params = GR_GL_FALSE; |
GrGLuint id = fBoundBuffers[GetBufferIndex(target)]; |
if (id > 0) { |
- Buffer* buffer = fBufferManager.lookUp(id); |
+ BufferObj* buffer = fBufferManager.lookUp(id); |
if (buffer->mapped()) { |
*params = GR_GL_TRUE; |
} |
@@ -722,20 +448,14 @@ |
} |
constexpr int static kNumBufferTargets = 6; |
- TGLObjectManager<Buffer> fBufferManager; |
- GrGLuint fBoundBuffers[kNumBufferTargets]; |
- TGLObjectManager<Framebuffer> fFramebufferManager; |
- GrGLuint fCurrDrawFramebuffer; |
- GrGLuint fCurrReadFramebuffer; |
- TGLObjectManager<Renderbuffer> fRenderbufferManager; |
- GrGLuint fCurrRenderbuffer; |
- TGLObjectManager<Texture> fTextureManager; |
- GrGLuint fCurrProgramID; |
- GrGLuint fCurrShaderID; |
- GrGLuint fCurrGenericID; |
- GrGLuint fCurrUniformLocation; |
- GrGLuint fCurrPathID; |
- SkTArray<const char*> fExtensions; |
+ BufferManager fBufferManager; |
+ GrGLuint fBoundBuffers[kNumBufferTargets]; |
+ GrGLuint fCurrProgramID; |
+ GrGLuint fCurrShaderID; |
+ GrGLuint fCurrGenericID; |
+ GrGLuint fCurrUniformLocation; |
+ GrGLuint fCurrPathID; |
+ SkTArray<const char*> fExtensions; |
// the OpenGLES 2.0 spec says this must be >= 128 |
static const GrGLint kDefaultMaxVertexUniformVectors = 128; |
@@ -748,19 +468,6 @@ |
// the OpenGLES 2.0 spec says this must be >= 8 |
static const GrGLint kDefaultMaxVaryingVectors = 8; |
- |
- GrGLuint getBoundFramebufferID(GrGLenum target) { |
- switch (target) { |
- case GR_GL_FRAMEBUFFER: |
- case GR_GL_DRAW_FRAMEBUFFER: |
- return fCurrDrawFramebuffer; |
- case GR_GL_READ_FRAMEBUFFER: |
- return fCurrReadFramebuffer; |
- default: |
- SK_ABORT("Invalid framebuffer target."); |
- return 0; |
- } |
- } |
const GrGLubyte* CombinedExtensionString() { |
static SkString gExtString; |