зеркало из https://github.com/mozilla/moz-skia.git
Add optional per-gl-func client callback.
Review URL: http://codereview.appspot.com/4964055/ git-svn-id: http://skia.googlecode.com/svn/trunk@2207 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
9399cac0a1
Коммит
56bfc5acc2
|
@ -68,6 +68,15 @@
|
|||
* However, this can cause a performance decrease on Chrome cmd buffer because
|
||||
* it will create a new allocation and memset the whole thing to zero (for
|
||||
* security reasons). Defaults to 1 (enabled).
|
||||
*
|
||||
* GR_GL_PER_GL_FUNC_CALLBACK: When set to 1 the GrGLInterface object provides
|
||||
* a function pointer that is called just before every gl function. The ptr must
|
||||
* be valid (i.e. there is no NULL check). However, by default the callback will
|
||||
* be set to a function that does nothing. The signature of the function is:
|
||||
* void function(const GrGLInterface*)
|
||||
* It is not extern "C".
|
||||
* The GrGLInterface field fCallback specifies the function ptr and there is an
|
||||
* additional field fCallbackData of type intptr_t for client data.
|
||||
*/
|
||||
|
||||
#if !defined(GR_GL_LOG_CALLS)
|
||||
|
@ -98,6 +107,10 @@
|
|||
#define GR_GL_USE_BUFFER_DATA_NULL_HINT 1
|
||||
#endif
|
||||
|
||||
#if !defined(GR_GL_PER_GL_FUNC_CALLBACK)
|
||||
#define GR_GL_PER_GL_FUNC_CALLBACK 0
|
||||
#endif
|
||||
|
||||
#if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES)
|
||||
#error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES"
|
||||
#endif
|
||||
|
@ -175,13 +188,37 @@ extern void GrGLClearErr(const GrGLInterface* gl);
|
|||
#define GR_GL_LOG_CALLS_IMPL(X)
|
||||
#endif
|
||||
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
#define GR_GL_CALLBACK_IMPL(IFACE) (IFACE)->fCallback(IFACE)
|
||||
#else
|
||||
#define GR_GL_CALLBACK_IMPL(IFACE)
|
||||
#endif
|
||||
|
||||
#define GR_GL_CALL(IFACE, X) \
|
||||
GR_GL_CALL_NOERRCHECK(IFACE, X) \
|
||||
GR_GL_CHECK_ERROR_IMPL(IFACE, X)
|
||||
do { \
|
||||
GR_GL_CALL_NOERRCHECK(IFACE, X); \
|
||||
GR_GL_CHECK_ERROR_IMPL(IFACE, X); \
|
||||
} while (false)
|
||||
|
||||
#define GR_GL_CALL_NOERRCHECK(IFACE, X) \
|
||||
IFACE->f##X; \
|
||||
GR_GL_LOG_CALLS_IMPL(X);
|
||||
do { \
|
||||
GR_GL_CALLBACK_IMPL(IFACE); \
|
||||
(IFACE)->f##X; \
|
||||
GR_GL_LOG_CALLS_IMPL(X); \
|
||||
} while (false)
|
||||
|
||||
#define GR_GL_CALL_RET(IFACE, RET, X) \
|
||||
do { \
|
||||
GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X); \
|
||||
GR_GL_CHECK_ERROR_IMPL(IFACE, X); \
|
||||
} while (false)
|
||||
|
||||
#define GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X) \
|
||||
do { \
|
||||
GR_GL_CALLBACK_IMPL(IFACE); \
|
||||
(RET) = (IFACE)->f##X; \
|
||||
GR_GL_LOG_CALLS_IMPL(X); \
|
||||
} while (false)
|
||||
|
||||
#define GR_GL_GET_ERROR(IFACE) (IFACE)->fGetError()
|
||||
|
||||
|
|
|
@ -21,4 +21,7 @@
|
|||
// with NULL.
|
||||
#define GR_GL_USE_BUFFER_DATA_NULL_HINT 0
|
||||
|
||||
// chrome uses this to set the context on each GL call.
|
||||
#define GR_GL_PER_GL_FUNC_CALLBACK 1
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,10 @@ float gl_version_as_float(const GrGLInterface*);
|
|||
* also an implementation that does nothing. You can link in any of the provided
|
||||
* implementations or your own implementation that sets up the GL function
|
||||
* pointers for your specific platform.
|
||||
*
|
||||
* By defining GR_GL_PER_GL_CALL_IFACE_CALLBACK to 1 the client can specify a
|
||||
* callback function that will be called prior to each GL function call. See
|
||||
* comments in GrGLConfig.h
|
||||
*/
|
||||
|
||||
struct GrGLInterface;
|
||||
|
@ -217,6 +221,12 @@ extern "C" {
|
|||
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindFragDataLocationIndexedProc)(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name);
|
||||
} // extern "C"
|
||||
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
typedef void (*GrGLInterfaceCallbackProc)(const GrGLInterface*);
|
||||
typedef intptr_t GrGLInterfaceCallbackData;
|
||||
#endif
|
||||
|
||||
|
||||
enum GrGLCapability {
|
||||
kProbe_GrGLCapability = -1
|
||||
};
|
||||
|
@ -388,6 +398,12 @@ struct GR_API GrGLInterface : public GrRefCnt {
|
|||
// Dual Source Blending
|
||||
GrGLBindFragDataLocationIndexedProc fBindFragDataLocationIndexed;
|
||||
|
||||
// Per-GL func callback
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
GrGLInterfaceCallbackProc fCallback;
|
||||
GrGLInterfaceCallbackData fCallbackData;
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool validateShaderFunctions() const;
|
||||
bool validateFixedFunctions() const;
|
||||
|
|
|
@ -59,7 +59,9 @@ void* GrGLIndexBuffer::lock() {
|
|||
NULL,
|
||||
this->dynamic() ? GR_GL_DYNAMIC_DRAW :
|
||||
GR_GL_STATIC_DRAW));
|
||||
fLockPtr = GL_CALL(MapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
|
||||
GR_GL_CALL_RET(GPUGL->glInterface(),
|
||||
fLockPtr,
|
||||
MapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
|
||||
GR_GL_WRITE_ONLY));
|
||||
|
||||
return fLockPtr;
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
namespace {
|
||||
void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
|
||||
}
|
||||
#endif
|
||||
|
||||
static SkAutoTUnref<const GrGLInterface> gDefaultGLInterface;
|
||||
|
||||
void gl_version_from_string(int* major, int* minor,
|
||||
|
@ -234,6 +240,11 @@ GrGLInterface::GrGLInterface() {
|
|||
fMapBuffer = NULL;
|
||||
fUnmapBuffer = NULL;
|
||||
fBindFragDataLocationIndexed = NULL;
|
||||
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
fCallback = GrGLDefaultInterfaceCallback;
|
||||
fCallbackData = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -774,7 +774,8 @@ GrGLuint GrGLProgram::CompileShader(const GrGLInterface* gl,
|
|||
SK_TRACE_EVENT1("GrGLProgram::CompileShader",
|
||||
"stringCount", SkStringPrintf("%i", stringCnt).c_str());
|
||||
|
||||
GrGLuint shader = GR_GL_CALL(gl, CreateShader(type));
|
||||
GrGLuint shader;
|
||||
GR_GL_CALL_RET(gl, shader, CreateShader(type));
|
||||
if (0 == shader) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -813,7 +814,7 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(
|
|||
bool bindColorOut,
|
||||
bool bindDualSrcOut,
|
||||
CachedData* programData) const {
|
||||
programData->fProgramID = GR_GL_CALL(gl, CreateProgram());
|
||||
GR_GL_CALL_RET(gl, programData->fProgramID, CreateProgram());
|
||||
if (!programData->fProgramID) {
|
||||
return false;
|
||||
}
|
||||
|
@ -890,24 +891,24 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLInterface* gl,
|
|||
const GrGLint& progID = programData->fProgramID;
|
||||
|
||||
if (kUseUniform == programData->fUniLocations.fViewMatrixUni) {
|
||||
programData->fUniLocations.fViewMatrixUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID, VIEW_MATRIX_NAME));
|
||||
GR_GL_CALL_RET(gl, programData->fUniLocations.fViewMatrixUni,
|
||||
GetUniformLocation(progID, VIEW_MATRIX_NAME));
|
||||
GrAssert(kUnusedUniform != programData->fUniLocations.fViewMatrixUni);
|
||||
}
|
||||
if (kUseUniform == programData->fUniLocations.fColorUni) {
|
||||
programData->fUniLocations.fColorUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID, COL_UNI_NAME));
|
||||
GR_GL_CALL_RET(gl, programData->fUniLocations.fColorUni,
|
||||
GetUniformLocation(progID, COL_UNI_NAME));
|
||||
GrAssert(kUnusedUniform != programData->fUniLocations.fColorUni);
|
||||
}
|
||||
if (kUseUniform == programData->fUniLocations.fColorFilterUni) {
|
||||
programData->fUniLocations.fColorFilterUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID, COL_FILTER_UNI_NAME));
|
||||
GR_GL_CALL_RET(gl, programData->fUniLocations.fColorFilterUni,
|
||||
GetUniformLocation(progID, COL_FILTER_UNI_NAME));
|
||||
GrAssert(kUnusedUniform != programData->fUniLocations.fColorFilterUni);
|
||||
}
|
||||
|
||||
if (kUseUniform == programData->fUniLocations.fEdgesUni) {
|
||||
programData->fUniLocations.fEdgesUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID, EDGES_UNI_NAME));
|
||||
GR_GL_CALL_RET(gl, programData->fUniLocations.fEdgesUni,
|
||||
GetUniformLocation(progID, EDGES_UNI_NAME));
|
||||
GrAssert(kUnusedUniform != programData->fUniLocations.fEdgesUni);
|
||||
} else {
|
||||
programData->fUniLocations.fEdgesUni = kUnusedUniform;
|
||||
|
@ -919,57 +920,54 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLInterface* gl,
|
|||
if (kUseUniform == locations.fTextureMatrixUni) {
|
||||
GrStringBuilder texMName;
|
||||
tex_matrix_name(s, &texMName);
|
||||
locations.fTextureMatrixUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID, texMName.c_str()));
|
||||
GR_GL_CALL_RET(gl, locations.fTextureMatrixUni,
|
||||
GetUniformLocation(progID, texMName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fTextureMatrixUni);
|
||||
}
|
||||
|
||||
if (kUseUniform == locations.fSamplerUni) {
|
||||
GrStringBuilder samplerName;
|
||||
sampler_name(s, &samplerName);
|
||||
locations.fSamplerUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID,
|
||||
samplerName.c_str()));
|
||||
GR_GL_CALL_RET(gl, locations.fSamplerUni,
|
||||
GetUniformLocation(progID,samplerName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fSamplerUni);
|
||||
}
|
||||
|
||||
if (kUseUniform == locations.fNormalizedTexelSizeUni) {
|
||||
GrStringBuilder texelSizeName;
|
||||
normalized_texel_size_name(s, &texelSizeName);
|
||||
locations.fNormalizedTexelSizeUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID,
|
||||
texelSizeName.c_str()));
|
||||
GR_GL_CALL_RET(gl, locations.fNormalizedTexelSizeUni,
|
||||
GetUniformLocation(progID, texelSizeName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fNormalizedTexelSizeUni);
|
||||
}
|
||||
|
||||
if (kUseUniform == locations.fRadial2Uni) {
|
||||
GrStringBuilder radial2ParamName;
|
||||
radial2_param_name(s, &radial2ParamName);
|
||||
locations.fRadial2Uni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID,
|
||||
radial2ParamName.c_str()));
|
||||
GR_GL_CALL_RET(gl, locations.fRadial2Uni,
|
||||
GetUniformLocation(progID, radial2ParamName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fRadial2Uni);
|
||||
}
|
||||
|
||||
if (kUseUniform == locations.fTexDomUni) {
|
||||
GrStringBuilder texDomName;
|
||||
tex_domain_name(s, &texDomName);
|
||||
locations.fTexDomUni =
|
||||
GR_GL_CALL(gl, GetUniformLocation(progID,
|
||||
texDomName.c_str()));
|
||||
GR_GL_CALL_RET(gl, locations.fTexDomUni,
|
||||
GetUniformLocation(progID, texDomName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fTexDomUni);
|
||||
}
|
||||
|
||||
GrStringBuilder kernelName, imageIncrementName;
|
||||
convolve_param_names(s, &kernelName, &imageIncrementName);
|
||||
if (kUseUniform == locations.fKernelUni) {
|
||||
locations.fKernelUni = GR_GL_CALL(gl, GetUniformLocation(
|
||||
progID, kernelName.c_str()));
|
||||
GR_GL_CALL_RET(gl, locations.fKernelUni,
|
||||
GetUniformLocation(progID, kernelName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fKernelUni);
|
||||
}
|
||||
|
||||
if (kUseUniform == locations.fImageIncrementUni) {
|
||||
locations.fImageIncrementUni = GR_GL_CALL(gl, GetUniformLocation(progID,
|
||||
GR_GL_CALL_RET(gl, locations.fImageIncrementUni,
|
||||
GetUniformLocation(progID,
|
||||
imageIncrementName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fImageIncrementUni);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,9 @@ void* GrGLVertexBuffer::lock() {
|
|||
GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL,
|
||||
this->dynamic() ? GR_GL_DYNAMIC_DRAW :
|
||||
GR_GL_STATIC_DRAW));
|
||||
fLockPtr = GL_CALL(MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
|
||||
GR_GL_CALL_RET(GPUGL->glInterface(),
|
||||
fLockPtr,
|
||||
MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
|
||||
return fLockPtr;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -16,6 +16,7 @@ static const GrGLuint GR_MAX_GLUINT = ~0;
|
|||
static const GrGLint GR_INVAL_GLINT = ~0;
|
||||
|
||||
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
|
||||
#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
|
||||
|
||||
// we use a spare texture unit to avoid
|
||||
// mucking with the state of any of the stages.
|
||||
|
@ -173,7 +174,8 @@ static bool fbo_test(const GrGLInterface* gl, int w, int h) {
|
|||
GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_COLOR_ATTACHMENT0,
|
||||
GR_GL_TEXTURE_2D, testRTTex, 0));
|
||||
GrGLenum status = GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GrGLenum status;
|
||||
GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO));
|
||||
GR_GL_CALL(gl, DeleteTextures(1, &testRTTex));
|
||||
|
||||
|
@ -278,11 +280,15 @@ GrGpuGL::GrGpuGL(const GrGLInterface* gl, GrGLBinding glBinding)
|
|||
|
||||
GrGLClearErr(fGL);
|
||||
|
||||
const GrGLubyte* ext;
|
||||
GL_CALL_RET(ext, GetString(GR_GL_EXTENSIONS));
|
||||
if (gPrintStartupSpew) {
|
||||
const GrGLubyte* vendor = GL_CALL(GetString(GR_GL_VENDOR));
|
||||
const GrGLubyte* renderer = GL_CALL(GetString(GR_GL_RENDERER));
|
||||
const GrGLubyte* version = GL_CALL(GetString(GR_GL_VERSION));
|
||||
const GrGLubyte* ext = GL_CALL(GetString(GR_GL_EXTENSIONS));
|
||||
const GrGLubyte* vendor;
|
||||
const GrGLubyte* renderer;
|
||||
const GrGLubyte* version;
|
||||
GL_CALL_RET(vendor, GetString(GR_GL_VENDOR));
|
||||
GL_CALL_RET(renderer, GetString(GR_GL_RENDERER));
|
||||
GL_CALL_RET(version, GetString(GR_GL_VERSION));
|
||||
GrPrintf("------------------------- create GrGpuGL %p --------------\n",
|
||||
this);
|
||||
GrPrintf("------ VENDOR %s\n", vendor);
|
||||
|
@ -292,7 +298,7 @@ GrGpuGL::GrGpuGL(const GrGLInterface* gl, GrGLBinding glBinding)
|
|||
}
|
||||
|
||||
fGLVersion = gl_version_as_float(gl);
|
||||
fExtensionString = (const char*) GL_CALL(GetString(GR_GL_EXTENSIONS));
|
||||
fExtensionString = (const char*) ext;
|
||||
|
||||
this->resetDirtyFlags();
|
||||
|
||||
|
@ -953,7 +959,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
|
|||
GR_GL_COLOR_ATTACHMENT0,
|
||||
GR_GL_RENDERBUFFER,
|
||||
desc->fMSColorRenderbufferID));
|
||||
GrGLenum status = GL_CALL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
|
||||
goto FAILED;
|
||||
}
|
||||
|
@ -964,7 +970,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
|
|||
GR_GL_COLOR_ATTACHMENT0,
|
||||
GR_GL_TEXTURE_2D,
|
||||
texID, 0));
|
||||
status = GL_CALL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
|
||||
goto FAILED;
|
||||
}
|
||||
|
@ -1220,8 +1226,8 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
|
|||
GR_GL_DEPTH_ATTACHMENT,
|
||||
GR_GL_RENDERBUFFER, 0));
|
||||
#if GR_DEBUG
|
||||
GrGLenum status =
|
||||
GL_CALL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GrGLenum status;
|
||||
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GrAssert(GR_GL_FRAMEBUFFER_COMPLETE == status);
|
||||
#endif
|
||||
}
|
||||
|
@ -1245,7 +1251,8 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
|
|||
GR_GL_RENDERBUFFER, 0));
|
||||
}
|
||||
|
||||
GrGLenum status = GL_CALL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GrGLenum status;
|
||||
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
|
||||
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_STENCIL_ATTACHMENT,
|
||||
|
@ -1495,7 +1502,8 @@ void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
|
|||
++fStats.fRenderTargetChngCnt;
|
||||
#endif
|
||||
#if GR_DEBUG
|
||||
GrGLenum status = GL_CALL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
GrGLenum status;
|
||||
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
|
||||
GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче