class NullInterface : public GrGLTestInterface {
public:
NullInterface(bool enableNVPR)
- : fCurrArrayBuffer(0)
- , fCurrElementArrayBuffer(0)
- , fCurrPixelPackBuffer(0)
- , fCurrPixelUnpackBuffer(0)
- , fCurrProgramID(0)
+ : fCurrProgramID(0)
, fCurrShaderID(0)
, fCurrGenericID(0)
, fCurrUniformLocation(0)
, fCurrPathID(0) {
+ memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
fExtensions.push_back("GL_ARB_framebuffer_object");
fExtensions.push_back("GL_ARB_blend_func_extended");
fExtensions.push_back("GL_ARB_timer_query");
GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
GrGLenum usage) override {
- GrGLuint id = 0;
-
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- id = fCurrArrayBuffer;
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- id = fCurrElementArrayBuffer;
- break;
- case GR_GL_PIXEL_PACK_BUFFER:
- id = fCurrPixelPackBuffer;
- break;
- case GR_GL_PIXEL_UNPACK_BUFFER:
- id = fCurrPixelUnpackBuffer;
- break;
- default:
- SkFAIL("Unexpected target to nullGLBufferData");
- break;
- }
-
+ GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
if (id > 0) {
BufferObj* buffer = fBufferManager.lookUp(id);
buffer->allocate(size, (const GrGLchar*) data);
}
GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override {
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- fCurrArrayBuffer = buffer;
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- fCurrElementArrayBuffer = buffer;
- break;
- case GR_GL_PIXEL_PACK_BUFFER:
- fCurrPixelPackBuffer = buffer;
- break;
- case GR_GL_PIXEL_UNPACK_BUFFER:
- fCurrPixelUnpackBuffer = buffer;
- break;
- }
+ fBoundBuffers[GetBufferIndex(target)] = buffer;
}
// deleting a bound buffer has the side effect of binding 0
- GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
- for (int i = 0; i < n; ++i) {
- if (ids[i] == fCurrArrayBuffer) {
- fCurrArrayBuffer = 0;
- }
- if (ids[i] == fCurrElementArrayBuffer) {
- fCurrElementArrayBuffer = 0;
+ GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
+ // First potentially unbind the buffers.
+ for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
+ if (!fBoundBuffers[buffIdx]) {
+ continue;
}
- if (ids[i] == fCurrPixelPackBuffer) {
- fCurrPixelPackBuffer = 0;
- }
- if (ids[i] == fCurrPixelUnpackBuffer) {
- fCurrPixelUnpackBuffer = 0;
+ for (int i = 0; i < n; ++i) {
+ if (ids[i] == fBoundBuffers[buffIdx]) {
+ fBoundBuffers[buffIdx] = 0;
+ break;
+ }
}
+ }
+ // Then actually "delete" the buffers.
+ for (int i = 0; i < n; ++i) {
if (ids[i] > 0) {
BufferObj* buffer = fBufferManager.lookUp(ids[i]);
fBufferManager.free(buffer);
GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
GrGLbitfield access) override {
- GrGLuint id = 0;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- id = fCurrArrayBuffer;
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- id = fCurrElementArrayBuffer;
- break;
- case GR_GL_PIXEL_PACK_BUFFER:
- id = fCurrPixelPackBuffer;
- break;
- case GR_GL_PIXEL_UNPACK_BUFFER:
- id = fCurrPixelUnpackBuffer;
- break;
- }
-
+ GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
if (id > 0) {
// We just ignore the offset and length here.
BufferObj* buffer = fBufferManager.lookUp(id);
}
GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
- GrGLuint id = 0;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- id = fCurrArrayBuffer;
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- id = fCurrElementArrayBuffer;
- break;
- case GR_GL_PIXEL_PACK_BUFFER:
- id = fCurrPixelPackBuffer;
- break;
- case GR_GL_PIXEL_UNPACK_BUFFER:
- id = fCurrPixelUnpackBuffer;
- break;
- }
-
+ GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
if (id > 0) {
BufferObj* buffer = fBufferManager.lookUp(id);
SkASSERT(!buffer->mapped());
}
GrGLboolean unmapBuffer(GrGLenum target) override {
- GrGLuint id = 0;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- id = fCurrArrayBuffer;
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- id = fCurrElementArrayBuffer;
- break;
- case GR_GL_PIXEL_PACK_BUFFER:
- id = fCurrPixelPackBuffer;
- break;
- case GR_GL_PIXEL_UNPACK_BUFFER:
- id = fCurrPixelUnpackBuffer;
- break;
- }
+ GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
if (id > 0) {
BufferObj* buffer = fBufferManager.lookUp(id);
SkASSERT(buffer->mapped());
switch (pname) {
case GR_GL_BUFFER_MAPPED: {
*params = GR_GL_FALSE;
- GrGLuint id = 0;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- id = fCurrArrayBuffer;
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- id = fCurrElementArrayBuffer;
- break;
- case GR_GL_PIXEL_PACK_BUFFER:
- id = fCurrPixelPackBuffer;
- break;
- case GR_GL_PIXEL_UNPACK_BUFFER:
- id = fCurrPixelUnpackBuffer;
- break;
- }
+ GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
if (id > 0) {
BufferObj* buffer = fBufferManager.lookUp(id);
if (buffer->mapped()) {
private:
+ inline int static GetBufferIndex(GrGLenum glTarget) {
+ switch (glTarget) {
+ default: SkFAIL("Unexpected GL target to GetBufferIndex");
+ case GR_GL_ARRAY_BUFFER: return 0;
+ case GR_GL_ELEMENT_ARRAY_BUFFER: return 1;
+ case GR_GL_TEXTURE_BUFFER: return 2;
+ case GR_GL_DRAW_INDIRECT_BUFFER: return 3;
+ case GR_GL_PIXEL_PACK_BUFFER: return 4;
+ case GR_GL_PIXEL_UNPACK_BUFFER: return 5;
+ }
+ }
+ constexpr int static kNumBufferTargets = 6;
+
BufferManager fBufferManager;
- GrGLuint fCurrArrayBuffer;
- GrGLuint fCurrElementArrayBuffer;
- GrGLuint fCurrPixelPackBuffer;
- GrGLuint fCurrPixelUnpackBuffer;
+ GrGLuint fBoundBuffers[kNumBufferTargets];
GrGLuint fCurrProgramID;
GrGLuint fCurrShaderID;
GrGLuint fCurrGenericID;
DebugInterface()
: fCurrGenericID(0)
, fCurrTextureUnit(0)
- , fArrayBuffer(nullptr)
- , fElementArrayBuffer(nullptr)
, fVertexArray(nullptr)
, fPackRowLength(0)
, fUnpackRowLength(0)
fTextureUnits[i]->ref();
fTextureUnits[i]->setNumber(i);
}
+ memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
this->init(kGL_GrGLStandard);
}
}
fObjects.reset();
- fArrayBuffer = nullptr;
- fElementArrayBuffer = nullptr;
+ memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
fVertexArray = nullptr;
this->report();
////////////////////////////////////////////////////////////////////////////////
GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
GrGLenum usage) override {
- GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
- GR_GL_ELEMENT_ARRAY_BUFFER == target);
GrAlwaysAssert(size >= 0);
GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
GR_GL_STATIC_DRAW == usage ||
GR_GL_DYNAMIC_DRAW == usage);
- GrBufferObj *buffer = nullptr;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- buffer = this->getArrayBuffer();
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- buffer = this->getElementArrayBuffer();
- break;
- default:
- SkFAIL("Unexpected target to glBufferData");
- break;
- }
-
+ GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
GrAlwaysAssert(buffer);
GrAlwaysAssert(buffer->getBound());
}
GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override {
- GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes);
// 0 is a permissible bufferID - it unbinds the current buffer
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- this->setArrayBuffer(buffer);
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- this->setElementArrayBuffer(buffer);
- break;
- default:
- SkFAIL("Unexpected target to glBindBuffer");
- break;
- }
+ this->setBuffer(GetBufferIndex(target), buffer);
}
// deleting a bound buffer has the side effect of binding 0
GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
// first potentially unbind the buffers
- for (int i = 0; i < n; ++i) {
-
- if (this->getArrayBuffer() &&
- ids[i] == this->getArrayBuffer()->getID()) {
- // this ID is the current array buffer
- this->setArrayBuffer(nullptr);
+ for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
+ GrBufferObj* buffer = fBoundBuffers[buffIdx];
+ if (!buffer) {
+ continue;
}
- if (this->getElementArrayBuffer() &&
- ids[i] == this->getElementArrayBuffer()->getID()) {
- // this ID is the current element array buffer
- this->setElementArrayBuffer(nullptr);
+ for (int i = 0; i < n; ++i) {
+ if (ids[i] == buffer->getID()) {
+ this->setBuffer(buffIdx, nullptr);
+ break;
+ }
}
}
// map a buffer to the caller's address space
GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
GrGLbitfield access) override {
- GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
- GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
// We only expect read access and we expect that the buffer or range is always invalidated.
GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access));
GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access);
- GrBufferObj *buffer = nullptr;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- buffer = this->getArrayBuffer();
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- buffer = this->getElementArrayBuffer();
- break;
- default:
- SkFAIL("Unexpected target to glMapBufferRange");
- break;
- }
-
+ GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
if (buffer) {
GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
GrAlwaysAssert(!buffer->getMapped());
GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
-
- GrBufferObj *buffer = nullptr;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- buffer = this->getArrayBuffer();
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- buffer = this->getElementArrayBuffer();
- break;
- default:
- SkFAIL("Unexpected target to glMapBuffer");
- break;
- }
-
+ GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
return this->mapBufferRange(target, 0, buffer->getSize(),
GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT);
}
// remove a buffer from the caller's address space
// TODO: check if the "access" method from "glMapBuffer" was honored
GrGLboolean unmapBuffer(GrGLenum target) override {
- GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
- GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
- GrBufferObj *buffer = nullptr;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- buffer = this->getArrayBuffer();
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- buffer = this->getElementArrayBuffer();
- break;
- default:
- SkFAIL("Unexpected target to glUnmapBuffer");
- break;
- }
-
+ GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
if (buffer) {
GrAlwaysAssert(buffer->getMapped());
buffer->resetMapped();
GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset,
GrGLsizeiptr length) override {
- GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
- GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
- GrBufferObj *buffer = nullptr;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- buffer = this->getArrayBuffer();
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- buffer = this->getElementArrayBuffer();
- break;
- default:
- SkFAIL("Unexpected target to glUnmapBuffer");
- break;
- }
-
+ GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
if (buffer) {
GrAlwaysAssert(buffer->getMapped());
GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override {
- GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
- GR_GL_ELEMENT_ARRAY_BUFFER == target);
GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
GR_GL_BUFFER_USAGE == value);
- GrBufferObj *buffer = nullptr;
- switch (target) {
- case GR_GL_ARRAY_BUFFER:
- buffer = this->getArrayBuffer();
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- buffer = this->getElementArrayBuffer();
- break;
- }
-
+ GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
GrAlwaysAssert(buffer);
switch (value) {
}
private:
+ inline int static GetBufferIndex(GrGLenum glTarget) {
+ switch (glTarget) {
+ default: SkFAIL("Unexpected GL target to GetBufferIndex");
+ case GR_GL_ARRAY_BUFFER: return 0;
+ case GR_GL_ELEMENT_ARRAY_BUFFER: return 1;
+ case GR_GL_TEXTURE_BUFFER: return 2;
+ case GR_GL_DRAW_INDIRECT_BUFFER: return 3;
+ }
+ }
+ constexpr int static kNumBufferTargets = 4;
+
// the OpenGLES 2.0 spec says this must be >= 128
static const GrGLint kDefaultMaxVertexUniformVectors = 128;
GrGLuint fCurrGenericID;
GrGLuint fCurrTextureUnit;
GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits];
- GrBufferObj* fArrayBuffer;
- GrBufferObj* fElementArrayBuffer;
+ GrBufferObj* fBoundBuffers[kNumBufferTargets];
GrVertexArrayObj* fVertexArray;
GrGLint fPackRowLength;
GrGLint fUnpackRowLength;
return fTextureUnits[unit];
}
- void setArrayBuffer(GrBufferObj *arrayBuffer) {
- if (fArrayBuffer) {
+ GrGLvoid setBuffer(int buffIdx, GrBufferObj* buffer) {
+ if (fBoundBuffers[buffIdx]) {
// automatically break the binding of the old buffer
- GrAlwaysAssert(fArrayBuffer->getBound());
- fArrayBuffer->resetBound();
-
- GrAlwaysAssert(!fArrayBuffer->getDeleted());
- fArrayBuffer->unref();
- }
-
- fArrayBuffer = arrayBuffer;
+ GrAlwaysAssert(fBoundBuffers[buffIdx]->getBound());
+ fBoundBuffers[buffIdx]->resetBound();
- if (fArrayBuffer) {
- GrAlwaysAssert(!fArrayBuffer->getDeleted());
- fArrayBuffer->ref();
-
- GrAlwaysAssert(!fArrayBuffer->getBound());
- fArrayBuffer->setBound();
+ GrAlwaysAssert(!fBoundBuffers[buffIdx]->getDeleted());
+ fBoundBuffers[buffIdx]->unref();
}
- }
- GrBufferObj* getArrayBuffer() { return fArrayBuffer; }
- void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
- if (fElementArrayBuffer) {
- // automatically break the binding of the old buffer
- GrAlwaysAssert(fElementArrayBuffer->getBound());
- fElementArrayBuffer->resetBound();
+ if (buffer) {
+ GrAlwaysAssert(!buffer->getDeleted());
+ buffer->ref();
- GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
- fElementArrayBuffer->unref();
+ GrAlwaysAssert(!buffer->getBound());
+ buffer->setBound();
}
- fElementArrayBuffer = elementArrayBuffer;
-
- if (fElementArrayBuffer) {
- GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
- fElementArrayBuffer->ref();
-
- GrAlwaysAssert(!fElementArrayBuffer->getBound());
- fElementArrayBuffer->setBound();
- }
+ fBoundBuffers[buffIdx] = buffer;
}
- GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
-
void setVertexArray(GrVertexArrayObj* vertexArray) {
if (vertexArray) {
SkASSERT(!vertexArray->getDeleted());