Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1021)

Unified Diff: tools/gpu/gl/debug/DebugGLContext.cpp

Issue 1850543003: Revert of rename sk_gpu_test::GLContext to sk_gpu_test::GLTestContext (Closed) Base URL: https://chromium.googlesource.com/skia.git@move
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gpu/gl/debug/DebugGLContext.h ('k') | tools/gpu/gl/debug/DebugGLTestContext.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gpu/gl/debug/DebugGLContext.cpp
diff --git a/tools/gpu/gl/debug/DebugGLContext.cpp b/tools/gpu/gl/debug/DebugGLContext.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4cbbea6802f83606aa376da8319c2f838adf058
--- /dev/null
+++ b/tools/gpu/gl/debug/DebugGLContext.cpp
@@ -0,0 +1,1256 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "DebugGLContext.h"
+
+#include "GrBufferObj.h"
+#include "GrFrameBufferObj.h"
+#include "GrProgramObj.h"
+#include "GrRenderBufferObj.h"
+#include "GrShaderObj.h"
+#include "GrTextureObj.h"
+#include "GrTextureUnitObj.h"
+#include "GrVertexArrayObj.h"
+#include "gl/GrGLTestInterface.h"
+
+#include "SkMutex.h"
+
+namespace {
+
+// Helper macro to make creating an object (where you need to get back a derived type) easier
+#define CREATE(className, classEnum) \
+ reinterpret_cast<className *>(this->createObj(classEnum))
+
+// Helper macro to make creating an object (where you need to get back a derived type) easier
+#define FIND(id, className, classEnum) \
+ reinterpret_cast<className *>(this->findObject(id, classEnum))
+
+class DebugInterface : public GrGLTestInterface {
+public:
+ DebugInterface()
+ : fCurrGenericID(0)
+ , fCurrTextureUnit(0)
+ , fArrayBuffer(nullptr)
+ , fElementArrayBuffer(nullptr)
+ , fVertexArray(nullptr)
+ , fPackRowLength(0)
+ , fUnpackRowLength(0)
+ , fPackAlignment(4)
+ , fFrameBuffer(nullptr)
+ , fRenderBuffer(nullptr)
+ , fProgram(nullptr)
+ , fAbandoned(false) {
+ for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+ fTextureUnits[i] =
+ reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit_ObjTypes));
+ fTextureUnits[i]->ref();
+ fTextureUnits[i]->setNumber(i);
+ }
+ this->init(kGL_GrGLStandard);
+ }
+
+ ~DebugInterface() override {
+ // unref & delete the texture units first so they don't show up on the leak report
+ for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+ fTextureUnits[i]->unref();
+ fTextureUnits[i]->deleteAction();
+ }
+ for (int i = 0; i < fObjects.count(); ++i) {
+ delete fObjects[i];
+ }
+ fObjects.reset();
+
+ fArrayBuffer = nullptr;
+ fElementArrayBuffer = nullptr;
+ fVertexArray = nullptr;
+
+ this->report();
+ }
+
+ void abandon() const override { fAbandoned = true; }
+
+ GrGLvoid activeTexture(GrGLenum texture) override {
+ // Ganesh offsets the texture unit indices
+ texture -= GR_GL_TEXTURE0;
+ GrAlwaysAssert(texture < kDefaultMaxTextureUnits);
+ fCurrTextureUnit = texture;
+ }
+
+ GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override {
+
+ GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
+ GrAlwaysAssert(program);
+
+ GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
+ GrAlwaysAssert(shader);
+
+ program->AttachShader(shader);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override {
+ GrAlwaysAssert(target == GR_GL_TEXTURE_2D ||
+ target == GR_GL_TEXTURE_RECTANGLE ||
+ target == GR_GL_TEXTURE_EXTERNAL);
+
+ // a textureID of 0 is acceptable - it binds to the default texture target
+ GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
+
+ this->setTexture(texture);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ 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;
+ }
+
+ GrAlwaysAssert(buffer);
+ GrAlwaysAssert(buffer->getBound());
+
+ buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
+ buffer->setUsage(usage);
+ }
+
+
+ GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override {
+
+ switch (pname) {
+ case GR_GL_UNPACK_ROW_LENGTH:
+ fUnpackRowLength = param;
+ break;
+ case GR_GL_PACK_ROW_LENGTH:
+ fPackRowLength = param;
+ break;
+ case GR_GL_UNPACK_ALIGNMENT:
+ break;
+ case GR_GL_PACK_ALIGNMENT:
+ fPackAlignment = param;
+ break;
+ default:
+ GrAlwaysAssert(false);
+ break;
+ }
+ }
+
+ GrGLvoid readPixels(GrGLint x,
+ GrGLint y,
+ GrGLsizei width,
+ GrGLsizei height,
+ GrGLenum format,
+ GrGLenum type,
+ GrGLvoid* pixels) override {
+
+ GrGLint pixelsInRow = width;
+ if (fPackRowLength > 0) {
+ pixelsInRow = fPackRowLength;
+ }
+
+ GrGLint componentsPerPixel = 0;
+
+ switch (format) {
+ case GR_GL_RGBA:
+ // fallthrough
+ case GR_GL_BGRA:
+ componentsPerPixel = 4;
+ break;
+ case GR_GL_RGB:
+ componentsPerPixel = 3;
+ break;
+ case GR_GL_RED:
+ componentsPerPixel = 1;
+ break;
+ default:
+ GrAlwaysAssert(false);
+ break;
+ }
+
+ GrGLint alignment = fPackAlignment;
+
+ GrGLint componentSize = 0; // size (in bytes) of a single component
+
+ switch (type) {
+ case GR_GL_UNSIGNED_BYTE:
+ componentSize = 1;
+ break;
+ default:
+ GrAlwaysAssert(false);
+ break;
+ }
+
+ GrGLint rowStride = 0; // number of components (not bytes) to skip
+ if (componentSize >= alignment) {
+ rowStride = componentsPerPixel * pixelsInRow;
+ } else {
+ float fTemp =
+ sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
+ static_cast<float>(alignment));
+ rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
+ }
+
+ GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
+ for (int y = 0; y < height; ++y) {
+ memset(scanline, 0, componentsPerPixel * componentSize * width);
+ scanline += rowStride;
+ }
+ }
+
+ GrGLvoid useProgram(GrGLuint programID) override {
+
+ // A programID of 0 is legal
+ GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
+
+ this->useProgram(program);
+ }
+
+ GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override {
+
+ GrAlwaysAssert(GR_GL_FRAMEBUFFER == target ||
+ GR_GL_READ_FRAMEBUFFER == target ||
+ GR_GL_DRAW_FRAMEBUFFER);
+
+ // a frameBufferID of 0 is acceptable - it binds to the default
+ // frame buffer
+ GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj,
+ kFrameBuffer_ObjTypes);
+
+ this->setFrameBuffer(frameBuffer);
+ }
+
+ GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override {
+
+ GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
+
+ // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
+ GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj,
+ kRenderBuffer_ObjTypes);
+
+ this->setRenderBuffer(renderBuffer);
+ }
+
+ GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override {
+ // first potentially unbind the texture
+ for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+ GrTextureUnitObj *pTU = this->getTextureUnit(i);
+
+ if (pTU->getTexture()) {
+ for (int j = 0; j < n; ++j) {
+
+ if (textures[j] == pTU->getTexture()->getID()) {
+ // this ID is the current texture - revert the binding to 0
+ pTU->setTexture(nullptr);
+ }
+ }
+ }
+ }
+
+ // TODO: fuse the following block with DeleteRenderBuffers?
+ // Open GL will remove a deleted render buffer from the active
+ // frame buffer but not from any other frame buffer
+ if (this->getFrameBuffer()) {
+
+ GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
+
+ for (int i = 0; i < n; ++i) {
+
+ if (frameBuffer->getColor() &&
+ textures[i] == frameBuffer->getColor()->getID()) {
+ frameBuffer->setColor(nullptr);
+ }
+ if (frameBuffer->getDepth() &&
+ textures[i] == frameBuffer->getDepth()->getID()) {
+ frameBuffer->setDepth(nullptr);
+ }
+ if (frameBuffer->getStencil() &&
+ textures[i] == frameBuffer->getStencil()->getID()) {
+ frameBuffer->setStencil(nullptr);
+ }
+ }
+ }
+
+ // then actually "delete" the buffers
+ for (int i = 0; i < n; ++i) {
+ GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjTypes);
+ GrAlwaysAssert(buffer);
+
+ // OpenGL gives no guarantees if a texture is deleted while attached to
+ // something other than the currently bound frame buffer
+ GrAlwaysAssert(!buffer->getBound());
+
+ GrAlwaysAssert(!buffer->getDeleted());
+ buffer->deleteAction();
+ }
+
+ }
+
+ GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override {
+
+ // first potentially unbind the buffers
+ if (this->getFrameBuffer()) {
+ for (int i = 0; i < n; ++i) {
+
+ if (frameBuffers[i] ==
+ this->getFrameBuffer()->getID()) {
+ // this ID is the current frame buffer - rebind to the default
+ this->setFrameBuffer(nullptr);
+ }
+ }
+ }
+
+ // then actually "delete" the buffers
+ for (int i = 0; i < n; ++i) {
+ GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj,
+ kFrameBuffer_ObjTypes);
+ GrAlwaysAssert(buffer);
+
+ GrAlwaysAssert(!buffer->getDeleted());
+ buffer->deleteAction();
+ }
+ }
+
+ GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override {
+
+ // first potentially unbind the buffers
+ if (this->getRenderBuffer()) {
+ for (int i = 0; i < n; ++i) {
+
+ if (renderBuffers[i] ==
+ this->getRenderBuffer()->getID()) {
+ // this ID is the current render buffer - make no
+ // render buffer be bound
+ this->setRenderBuffer(nullptr);
+ }
+ }
+ }
+
+ // TODO: fuse the following block with DeleteTextures?
+ // Open GL will remove a deleted render buffer from the active frame
+ // buffer but not from any other frame buffer
+ if (this->getFrameBuffer()) {
+
+ GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
+
+ for (int i = 0; i < n; ++i) {
+
+ if (frameBuffer->getColor() &&
+ renderBuffers[i] == frameBuffer->getColor()->getID()) {
+ frameBuffer->setColor(nullptr);
+ }
+ if (frameBuffer->getDepth() &&
+ renderBuffers[i] == frameBuffer->getDepth()->getID()) {
+ frameBuffer->setDepth(nullptr);
+ }
+ if (frameBuffer->getStencil() &&
+ renderBuffers[i] == frameBuffer->getStencil()->getID()) {
+ frameBuffer->setStencil(nullptr);
+ }
+ }
+ }
+
+ // then actually "delete" the buffers
+ for (int i = 0; i < n; ++i) {
+ GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj,
+ kRenderBuffer_ObjTypes);
+ GrAlwaysAssert(buffer);
+
+ // OpenGL gives no guarantees if a render buffer is deleted
+ // while attached to something other than the currently
+ // bound frame buffer
+ GrAlwaysAssert(!buffer->getColorBound());
+ GrAlwaysAssert(!buffer->getDepthBound());
+ // However, at GrContext destroy time we release all GrRsources and so stencil buffers
+ // may get deleted before FBOs that refer to them.
+ //GrAlwaysAssert(!buffer->getStencilBound());
+
+ GrAlwaysAssert(!buffer->getDeleted());
+ buffer->deleteAction();
+ }
+ }
+
+ GrGLvoid framebufferRenderbuffer(GrGLenum target,
+ GrGLenum attachment,
+ GrGLenum renderbuffertarget,
+ GrGLuint renderBufferID) override {
+
+ GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
+ GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
+ GR_GL_DEPTH_ATTACHMENT == attachment ||
+ GR_GL_STENCIL_ATTACHMENT == attachment);
+ GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
+
+ GrFrameBufferObj *framebuffer = this->getFrameBuffer();
+ // A render buffer cannot be attached to the default framebuffer
+ GrAlwaysAssert(framebuffer);
+
+ // a renderBufferID of 0 is acceptable - it unbinds the current
+ // render buffer
+ GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj,
+ kRenderBuffer_ObjTypes);
+
+ switch (attachment) {
+ case GR_GL_COLOR_ATTACHMENT0:
+ framebuffer->setColor(renderbuffer);
+ break;
+ case GR_GL_DEPTH_ATTACHMENT:
+ framebuffer->setDepth(renderbuffer);
+ break;
+ case GR_GL_STENCIL_ATTACHMENT:
+ framebuffer->setStencil(renderbuffer);
+ break;
+ default:
+ GrAlwaysAssert(false);
+ break;
+ };
+
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
+ GrGLuint textureID, GrGLint level) override {
+
+ GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
+ GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
+ GR_GL_DEPTH_ATTACHMENT == attachment ||
+ GR_GL_STENCIL_ATTACHMENT == attachment);
+ GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
+
+ GrFrameBufferObj *framebuffer = this->getFrameBuffer();
+ // A texture cannot be attached to the default framebuffer
+ GrAlwaysAssert(framebuffer);
+
+ // A textureID of 0 is allowed - it unbinds the currently bound texture
+ GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
+ if (texture) {
+ // The texture shouldn't be bound to a texture unit - this
+ // could lead to a feedback loop
+ GrAlwaysAssert(!texture->getBound());
+ }
+
+ GrAlwaysAssert(0 == level);
+
+ switch (attachment) {
+ case GR_GL_COLOR_ATTACHMENT0:
+ framebuffer->setColor(texture);
+ break;
+ case GR_GL_DEPTH_ATTACHMENT:
+ framebuffer->setDepth(texture);
+ break;
+ case GR_GL_STENCIL_ATTACHMENT:
+ framebuffer->setStencil(texture);
+ break;
+ default:
+ GrAlwaysAssert(false);
+ break;
+ };
+ }
+
+ GrGLuint createProgram() override {
+
+ GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes);
+
+ return program->getID();
+ }
+
+ GrGLuint createShader(GrGLenum type) override {
+
+ GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
+ GR_GL_FRAGMENT_SHADER == type);
+
+ GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes);
+ shader->setType(type);
+
+ return shader->getID();
+ }
+
+ GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; }
+
+ GrGLvoid deleteProgram(GrGLuint programID) override {
+
+ GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
+ GrAlwaysAssert(program);
+
+ if (program->getRefCount()) {
+ // someone is still using this program so we can't delete it here
+ program->setMarkedForDeletion();
+ } else {
+ program->deleteAction();
+ }
+ }
+
+ GrGLvoid deleteShader(GrGLuint shaderID) override {
+
+ GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
+ GrAlwaysAssert(shader);
+
+ if (shader->getRefCount()) {
+ // someone is still using this shader so we can't delete it here
+ shader->setMarkedForDeletion();
+ } else {
+ shader->deleteAction();
+ }
+ }
+
+ GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
+ this->genObjs(kBuffer_ObjTypes, n, ids);
+ }
+
+ GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override {
+ this->genObjs(kFrameBuffer_ObjTypes, n, ids);
+ }
+
+ GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override {
+ this->genObjs(kRenderBuffer_ObjTypes, n, ids);
+ }
+
+ GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override {
+ this->genObjs(kTexture_ObjTypes, n, ids);
+ }
+
+ GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override {
+ this->genObjs(kVertexArray_ObjTypes, n, ids);
+ }
+
+ GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
+
+ GrGLenum getError() override { return GR_GL_NO_ERROR; }
+
+ GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
+ // TODO: remove from Ganesh the #defines for gets we don't use.
+ // We would like to minimize gets overall due to performance issues
+ switch (pname) {
+ case GR_GL_CONTEXT_PROFILE_MASK:
+ *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
+ break;
+ case GR_GL_STENCIL_BITS:
+ *params = 8;
+ break;
+ case GR_GL_SAMPLES:
+ *params = 1;
+ break;
+ case GR_GL_FRAMEBUFFER_BINDING:
+ *params = 0;
+ break;
+ case GR_GL_VIEWPORT:
+ params[0] = 0;
+ params[1] = 0;
+ params[2] = 800;
+ params[3] = 600;
+ break;
+ case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
+ case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
+ case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ *params = 8;
+ break;
+ case GR_GL_MAX_TEXTURE_COORDS:
+ *params = 8;
+ break;
+ case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
+ *params = kDefaultMaxVertexUniformVectors;
+ break;
+ case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ *params = kDefaultMaxFragmentUniformVectors;
+ break;
+ case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+ *params = 16 * 4;
+ break;
+ case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ *params = 0;
+ break;
+ case GR_GL_COMPRESSED_TEXTURE_FORMATS:
+ break;
+ case GR_GL_MAX_TEXTURE_SIZE:
+ *params = 8192;
+ break;
+ case GR_GL_MAX_RENDERBUFFER_SIZE:
+ *params = 8192;
+ break;
+ case GR_GL_MAX_SAMPLES:
+ *params = 32;
+ break;
+ case GR_GL_MAX_VERTEX_ATTRIBS:
+ *params = kDefaultMaxVertexAttribs;
+ break;
+ case GR_GL_MAX_VARYING_VECTORS:
+ *params = kDefaultMaxVaryingVectors;
+ break;
+ case GR_GL_NUM_EXTENSIONS: {
+ GrGLint i = 0;
+ while (kExtensions[i++]);
+ *params = i;
+ break;
+ }
+ default:
+ SkFAIL("Unexpected pname to GetIntegerv");
+ }
+ }
+
+ GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
+ val[0] = val[1] = 0.5f;
+ }
+
+ GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
+ this->getShaderOrProgramiv(program, pname, params);
+ }
+
+ GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
+ char* infolog) override {
+ this->getInfoLog(program, bufsize, length, infolog);
+ }
+
+ GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
+ switch (pname) {
+ case GR_GL_CURRENT_QUERY:
+ *params = 0;
+ break;
+ case GR_GL_QUERY_COUNTER_BITS:
+ *params = 32;
+ break;
+ default:
+ SkFAIL("Unexpected pname passed GetQueryiv.");
+ }
+ }
+
+ GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
+ this->queryResult(id, pname, params);
+ }
+
+ GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
+ this->queryResult(id, pname, params);
+ }
+
+ GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
+ this->queryResult(id, pname, params);
+ }
+
+ GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
+ this->queryResult(id, pname, params);
+ }
+
+ GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
+ this->getShaderOrProgramiv(shader, pname, params);
+ }
+
+ GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
+ char* infolog) override {
+ this->getInfoLog(shader, bufsize, length, infolog);
+ }
+
+ const GrGLubyte* getString(GrGLenum name) override {
+ switch (name) {
+ case GR_GL_EXTENSIONS:
+ return CombinedExtensionString();
+ case GR_GL_VERSION:
+ return (const GrGLubyte*)"4.0 Debug GL";
+ case GR_GL_SHADING_LANGUAGE_VERSION:
+ return (const GrGLubyte*)"4.20.8 Debug GLSL";
+ case GR_GL_VENDOR:
+ return (const GrGLubyte*)"Debug Vendor";
+ case GR_GL_RENDERER:
+ return (const GrGLubyte*)"The Debug (Non-)Renderer";
+ default:
+ SkFAIL("Unexpected name passed to GetString");
+ return nullptr;
+ }
+ }
+
+ const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
+ switch (name) {
+ case GR_GL_EXTENSIONS: {
+ GrGLint count;
+ this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
+ if ((GrGLint)i <= count) {
+ return (const GrGLubyte*) kExtensions[i];
+ } else {
+ return nullptr;
+ }
+ }
+ default:
+ SkFAIL("Unexpected name passed to GetStringi");
+ return nullptr;
+ }
+ }
+
+ GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname,
+ GrGLint* params) override {
+ // we used to use this to query stuff about externally created textures,
+ // now we just require clients to tell us everything about the texture.
+ SkFAIL("Should never query texture parameters.");
+ }
+
+ GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override {
+ for (GrGLsizei i = 0; i < n; ++i) {
+ GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArray_ObjTypes);
+ GrAlwaysAssert(array);
+
+ // Deleting the current vertex array binds object 0
+ if (this->getVertexArray() == array) {
+ this->setVertexArray(nullptr);
+ }
+
+ if (array->getRefCount()) {
+ // someone is still using this vertex array so we can't delete it here
+ array->setMarkedForDeletion();
+ } else {
+ array->deleteAction();
+ }
+ }
+ }
+
+ GrGLvoid bindVertexArray(GrGLuint id) override {
+ GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTypes);
+ GrAlwaysAssert((0 == id) || array);
+ this->setVertexArray(array);
+ }
+
+ 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;
+ }
+ }
+
+ // 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);
+ }
+ if (this->getElementArrayBuffer() &&
+ ids[i] == this->getElementArrayBuffer()->getID()) {
+ // this ID is the current element array buffer
+ this->setElementArrayBuffer(nullptr);
+ }
+ }
+
+ // then actually "delete" the buffers
+ for (int i = 0; i < n; ++i) {
+ GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes);
+ GrAlwaysAssert(buffer);
+
+ GrAlwaysAssert(!buffer->getDeleted());
+ buffer->deleteAction();
+ }
+ }
+
+ // 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;
+ }
+
+ if (buffer) {
+ GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
+ GrAlwaysAssert(!buffer->getMapped());
+ buffer->setMapped(offset, length);
+ return buffer->getDataPtr() + offset;
+ }
+
+ GrAlwaysAssert(false);
+ return nullptr; // no buffer bound to the target
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ if (buffer) {
+ GrAlwaysAssert(buffer->getMapped());
+ buffer->resetMapped();
+ return GR_GL_TRUE;
+ }
+
+ GrAlwaysAssert(false);
+ return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
+ }
+
+ 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;
+ }
+
+ if (buffer) {
+ GrAlwaysAssert(buffer->getMapped());
+ GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
+ } else {
+ GrAlwaysAssert(false);
+ }
+ }
+
+ 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;
+ }
+
+ GrAlwaysAssert(buffer);
+
+ switch (value) {
+ case GR_GL_BUFFER_MAPPED:
+ *params = GR_GL_FALSE;
+ if (buffer)
+ *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
+ break;
+ case GR_GL_BUFFER_SIZE:
+ *params = 0;
+ if (buffer)
+ *params = SkToInt(buffer->getSize());
+ break;
+ case GR_GL_BUFFER_USAGE:
+ *params = GR_GL_STATIC_DRAW;
+ if (buffer)
+ *params = buffer->getUsage();
+ break;
+ default:
+ SkFAIL("Unexpected value to glGetBufferParamateriv");
+ break;
+ }
+ }
+
+private:
+ // the OpenGLES 2.0 spec says this must be >= 128
+ static const GrGLint kDefaultMaxVertexUniformVectors = 128;
+
+ // the OpenGLES 2.0 spec says this must be >=16
+ static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
+
+ // the OpenGLES 2.0 spec says this must be >= 8
+ static const GrGLint kDefaultMaxVertexAttribs = 8;
+
+ // the OpenGLES 2.0 spec says this must be >= 8
+ static const GrGLint kDefaultMaxVaryingVectors = 8;
+
+ // the OpenGLES 2.0 spec says this must be >= 2
+ static const GrGLint kDefaultMaxTextureUnits = 8;
+
+ static const char* kExtensions[];
+
+ GrGLuint fCurrGenericID;
+ GrGLuint fCurrTextureUnit;
+ GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits];
+ GrBufferObj* fArrayBuffer;
+ GrBufferObj* fElementArrayBuffer;
+ GrVertexArrayObj* fVertexArray;
+ GrGLint fPackRowLength;
+ GrGLint fUnpackRowLength;
+ GrGLint fPackAlignment;
+ GrFrameBufferObj* fFrameBuffer;
+ GrRenderBufferObj* fRenderBuffer;
+ GrProgramObj* fProgram;
+ mutable bool fAbandoned;
+ // global store of all objects
+ SkTArray<GrFakeRefObj *> fObjects;
+
+ static const GrGLubyte* CombinedExtensionString() {
+ static SkString gExtString;
+ static SkMutex gMutex;
+ gMutex.acquire();
+ if (0 == gExtString.size()) {
+ int i = 0;
+ while (kExtensions[i]) {
+ if (i > 0) {
+ gExtString.append(" ");
+ }
+ gExtString.append(kExtensions[i]);
+ ++i;
+ }
+ }
+ gMutex.release();
+ return (const GrGLubyte*) gExtString.c_str();
+ }
+
+ GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
+ for (int i = 0; i < n; ++i) {
+ ids[i] = ++fCurrGenericID;
+ }
+ }
+
+ GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
+ char* infolog) {
+ if (length) {
+ *length = 0;
+ }
+ if (bufsize > 0) {
+ *infolog = 0;
+ }
+ }
+
+ GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* params) {
+ switch (pname) {
+ case GR_GL_LINK_STATUS: // fallthru
+ case GR_GL_COMPILE_STATUS:
+ *params = GR_GL_TRUE;
+ break;
+ case GR_GL_INFO_LOG_LENGTH:
+ *params = 0;
+ break;
+ // we don't expect any other pnames
+ default:
+ SkFAIL("Unexpected pname to GetProgramiv");
+ break;
+ }
+ }
+
+ template <typename T>
+ void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
+ switch (pname) {
+ case GR_GL_QUERY_RESULT_AVAILABLE:
+ *params = GR_GL_TRUE;
+ break;
+ case GR_GL_QUERY_RESULT:
+ *params = 0;
+ break;
+ default:
+ SkFAIL("Unexpected pname passed to GetQueryObject.");
+ break;
+ }
+ }
+
+ enum ObjTypes {
+ kTexture_ObjTypes = 0,
+ kBuffer_ObjTypes,
+ kRenderBuffer_ObjTypes,
+ kFrameBuffer_ObjTypes,
+ kShader_ObjTypes,
+ kProgram_ObjTypes,
+ kTextureUnit_ObjTypes,
+ kVertexArray_ObjTypes,
+ kObjTypeCount
+ };
+
+ typedef GrFakeRefObj *(*Create)();
+
+ static Create gFactoryFunc[kObjTypeCount];
+
+ GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) {
+ for (int i = 0; i < n; ++i) {
+ GrAlwaysAssert(ids[i] == 0);
+ GrFakeRefObj *obj = this->createObj(type);
+ GrAlwaysAssert(obj);
+ ids[i] = obj->getID();
+ }
+ }
+
+ GrFakeRefObj* createObj(ObjTypes type) {
+ GrFakeRefObj *temp = (*gFactoryFunc[type])();
+
+ fObjects.push_back(temp);
+
+ return temp;
+ }
+
+ GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) {
+ for (int i = 0; i < fObjects.count(); ++i) {
+ if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) {
+ // The application shouldn't be accessing objects
+ // that (as far as OpenGL knows) were already deleted
+ GrAlwaysAssert(!fObjects[i]->getDeleted());
+ GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
+ return fObjects[i];
+ }
+ }
+ return nullptr;
+ }
+
+ GrTextureUnitObj* getTextureUnit(int unit) {
+ GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit);
+
+ return fTextureUnits[unit];
+ }
+
+ void setArrayBuffer(GrBufferObj *arrayBuffer) {
+ if (fArrayBuffer) {
+ // automatically break the binding of the old buffer
+ GrAlwaysAssert(fArrayBuffer->getBound());
+ fArrayBuffer->resetBound();
+
+ GrAlwaysAssert(!fArrayBuffer->getDeleted());
+ fArrayBuffer->unref();
+ }
+
+ fArrayBuffer = arrayBuffer;
+
+ if (fArrayBuffer) {
+ GrAlwaysAssert(!fArrayBuffer->getDeleted());
+ fArrayBuffer->ref();
+
+ GrAlwaysAssert(!fArrayBuffer->getBound());
+ fArrayBuffer->setBound();
+ }
+ }
+
+ GrBufferObj* getArrayBuffer() { return fArrayBuffer; }
+ void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
+ if (fElementArrayBuffer) {
+ // automatically break the binding of the old buffer
+ GrAlwaysAssert(fElementArrayBuffer->getBound());
+ fElementArrayBuffer->resetBound();
+
+ GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
+ fElementArrayBuffer->unref();
+ }
+
+ fElementArrayBuffer = elementArrayBuffer;
+
+ if (fElementArrayBuffer) {
+ GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
+ fElementArrayBuffer->ref();
+
+ GrAlwaysAssert(!fElementArrayBuffer->getBound());
+ fElementArrayBuffer->setBound();
+ }
+ }
+
+ GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
+
+ void setVertexArray(GrVertexArrayObj* vertexArray) {
+ if (vertexArray) {
+ SkASSERT(!vertexArray->getDeleted());
+ }
+ SkRefCnt_SafeAssign(fVertexArray, vertexArray);
+ }
+
+ GrVertexArrayObj* getVertexArray() { return fVertexArray; }
+
+ void setTexture(GrTextureObj *texture) {
+ fTextureUnits[fCurrTextureUnit]->setTexture(texture);
+ }
+
+ void setFrameBuffer(GrFrameBufferObj *frameBuffer) {
+ if (fFrameBuffer) {
+ GrAlwaysAssert(fFrameBuffer->getBound());
+ fFrameBuffer->resetBound();
+
+ GrAlwaysAssert(!fFrameBuffer->getDeleted());
+ fFrameBuffer->unref();
+ }
+
+ fFrameBuffer = frameBuffer;
+
+ if (fFrameBuffer) {
+ GrAlwaysAssert(!fFrameBuffer->getDeleted());
+ fFrameBuffer->ref();
+
+ GrAlwaysAssert(!fFrameBuffer->getBound());
+ fFrameBuffer->setBound();
+ }
+ }
+
+ GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
+
+ void setRenderBuffer(GrRenderBufferObj *renderBuffer) {
+ if (fRenderBuffer) {
+ GrAlwaysAssert(fRenderBuffer->getBound());
+ fRenderBuffer->resetBound();
+
+ GrAlwaysAssert(!fRenderBuffer->getDeleted());
+ fRenderBuffer->unref();
+ }
+
+ fRenderBuffer = renderBuffer;
+
+ if (fRenderBuffer) {
+ GrAlwaysAssert(!fRenderBuffer->getDeleted());
+ fRenderBuffer->ref();
+
+ GrAlwaysAssert(!fRenderBuffer->getBound());
+ fRenderBuffer->setBound();
+ }
+ }
+ GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
+
+ void useProgram(GrProgramObj *program) {
+ if (fProgram) {
+ GrAlwaysAssert(fProgram->getInUse());
+ fProgram->resetInUse();
+
+ GrAlwaysAssert(!fProgram->getDeleted());
+ fProgram->unref();
+ }
+
+ fProgram = program;
+
+ if (fProgram) {
+ GrAlwaysAssert(!fProgram->getDeleted());
+ fProgram->ref();
+
+ GrAlwaysAssert(!fProgram->getInUse());
+ fProgram->setInUse();
+ }
+ }
+
+ void report() const {
+ for (int i = 0; i < fObjects.count(); ++i) {
+ if (!fAbandoned) {
+ GrAlwaysAssert(0 == fObjects[i]->getRefCount());
+ GrAlwaysAssert(fObjects[i]->getDeleted());
+ }
+ }
+ }
+
+ typedef GrGLTestInterface INHERITED;
+};
+
+#undef CREATE
+#undef FIND
+
+DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = {
+ GrTextureObj::createGrTextureObj,
+ GrBufferObj::createGrBufferObj,
+ GrRenderBufferObj::createGrRenderBufferObj,
+ GrFrameBufferObj::createGrFrameBufferObj,
+ GrShaderObj::createGrShaderObj,
+ GrProgramObj::createGrProgramObj,
+ GrTextureUnitObj::createGrTextureUnitObj,
+ GrVertexArrayObj::createGrVertexArrayObj,
+};
+
+const char* DebugInterface::kExtensions[] = {
+ "GL_ARB_framebuffer_object",
+ "GL_ARB_blend_func_extended",
+ "GL_ARB_timer_query",
+ "GL_ARB_draw_buffers",
+ "GL_ARB_occlusion_query",
+ "GL_EXT_stencil_wrap",
+ nullptr, // signifies the end of the array.
+};
+
+class DebugGLContext : public sk_gpu_test::GLContext {
+public:
+ DebugGLContext() {
+ this->init(new DebugInterface());
+ }
+
+ ~DebugGLContext() override { this->teardown(); }
+
+private:
+ void onPlatformMakeCurrent() const override {}
+ void onPlatformSwapBuffers() const override {}
+ GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; }
+};
+} // anonymous namespace
+
+namespace sk_gpu_test {
+GLContext* CreateDebugGLContext() {
+ GLContext* ctx = new DebugGLContext();
+ if (ctx->isValid()) {
+ return ctx;
+ }
+ delete ctx;
+ return nullptr;
+}
+}
« no previous file with comments | « tools/gpu/gl/debug/DebugGLContext.h ('k') | tools/gpu/gl/debug/DebugGLTestContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698