diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/gl/GrGLContext.cpp | 11 | ||||
-rw-r--r-- | src/gpu/gl/GrGLContext.h | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 113 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 4 |
6 files changed, 87 insertions, 52 deletions
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp index 097fce23e2..7c99a1cd00 100644 --- a/src/gpu/gl/GrGLContext.cpp +++ b/src/gpu/gl/GrGLContext.cpp @@ -16,6 +16,7 @@ GrGLContextInfo& GrGLContextInfo::operator= (const GrGLContextInfo& ctxInfo) { fRenderer = ctxInfo.fRenderer; fExtensions = ctxInfo.fExtensions; fIsMesa = ctxInfo.fIsMesa; + fIsChromium = ctxInfo.fIsChromium; *fGLCaps = *ctxInfo.fGLCaps.get(); return *this; } @@ -28,6 +29,11 @@ bool GrGLContextInfo::initialize(const GrGLInterface* interface) { const GrGLubyte* verUByte; GR_GL_CALL_RET(interface, verUByte, GetString(GR_GL_VERSION)); const char* ver = reinterpret_cast<const char*>(verUByte); + + const GrGLubyte* rendererUByte; + GR_GL_CALL_RET(interface, rendererUByte, GetString(GR_GL_RENDERER)); + const char* renderer = reinterpret_cast<const char*>(rendererUByte); + GrGLBinding binding = GrGLGetBindingInUseFromString(ver); if (0 != binding && interface->validate(binding) && fExtensions.init(binding, interface)) { @@ -39,10 +45,12 @@ bool GrGLContextInfo::initialize(const GrGLInterface* interface) { fVendor = GrGLGetVendor(interface); - fRenderer = GrGLGetRenderer(interface); + fRenderer = GrGLGetRendererFromString(renderer); fIsMesa = GrGLIsMesaFromVersionString(ver); + fIsChromium = GrGLIsChromiumFromRendererString(renderer); + fGLCaps->init(*this, interface); return true; } @@ -61,6 +69,7 @@ void GrGLContextInfo::reset() { fVendor = kOther_GrGLVendor; fRenderer = kOther_GrGLRenderer; fIsMesa = false; + fIsChromium = false; fExtensions.reset(); fGLCaps->reset(); } diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h index b6e1ab3942..d2174c56c8 100644 --- a/src/gpu/gl/GrGLContext.h +++ b/src/gpu/gl/GrGLContext.h @@ -50,6 +50,10 @@ public: GrGLRenderer renderer() const { return fRenderer; } /** Is this a mesa-based driver. Does not mean it is the osmesa software rasterizer. */ bool isMesa() const { return fIsMesa; } + /** Are we running inside Chromium (using the command buffer)? We make some different tradeoffs + about what errors to check for because queries are synchronous. We should probably expose + this as an option for clients other than Chromium. */ + bool isChromium() const { return fIsChromium; } const GrGLCaps* caps() const { return fGLCaps.get(); } GrGLCaps* caps() { return fGLCaps; } const GrGLExtensions& extensions() const { return fExtensions; } @@ -78,6 +82,7 @@ private: GrGLRenderer fRenderer; GrGLExtensions fExtensions; bool fIsMesa; + bool fIsChromium; SkAutoTUnref<GrGLCaps> fGLCaps; }; diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 004fb04357..348ee2622f 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -590,25 +590,33 @@ bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { this->bindProgramLocations(programId); GL_CALL(LinkProgram(programId)); - GrGLint linked = GR_GL_INIT_ZERO; - GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked)); - if (!linked) { - GrGLint infoLen = GR_GL_INIT_ZERO; - GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen)); - SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger - if (infoLen > 0) { - // retrieve length even though we don't need it to workaround - // bug in chrome cmd buffer param validation. - GrGLsizei length = GR_GL_INIT_ZERO; - GL_CALL(GetProgramInfoLog(programId, - infoLen+1, - &length, - (char*)log.get())); - GrPrintf((char*)log.get()); + + // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. + bool checkLinked = !fGpu->ctxInfo().isChromium(); +#ifdef SK_DEBUG + checkLinked = true; +#endif + if (checkLinked) { + GrGLint linked = GR_GL_INIT_ZERO; + GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked)); + if (!linked) { + GrGLint infoLen = GR_GL_INIT_ZERO; + GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen)); + SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger + if (infoLen > 0) { + // retrieve length even though we don't need it to workaround + // bug in chrome cmd buffer param validation. + GrGLsizei length = GR_GL_INIT_ZERO; + GL_CALL(GetProgramInfoLog(programId, + infoLen+1, + &length, + (char*)log.get())); + GrPrintf((char*)log.get()); + } + SkDEBUGFAIL("Error linking program"); + GL_CALL(DeleteProgram(programId)); + return false; } - SkDEBUGFAIL("Error linking program"); - GL_CALL(DeleteProgram(programId)); - return false; } fUniformManager.getUniformLocations(programId, fUniforms); @@ -616,13 +624,14 @@ bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { return true; } -namespace { // Compiles a GL shader, attaches it to a program, and releases the shader's reference. // (That way there's no need to hang on to the GL shader id and delete it later.) -bool attach_shader(const GrGLInterface* gli, - GrGLuint programId, - GrGLenum type, - const SkString& shaderSrc) { +static bool attach_shader(const GrGLContext& glCtx, + GrGLuint programId, + GrGLenum type, + const SkString& shaderSrc) { + const GrGLInterface* gli = glCtx.interface(); + GrGLuint shaderId; GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); if (0 == shaderId) { @@ -632,28 +641,36 @@ bool attach_shader(const GrGLInterface* gli, const GrGLchar* sourceStr = shaderSrc.c_str(); GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); - - GrGLint compiled = GR_GL_INIT_ZERO; GR_GL_CALL(gli, CompileShader(shaderId)); - GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); - - if (!compiled) { - GrGLint infoLen = GR_GL_INIT_ZERO; - GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); - SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger - if (infoLen > 0) { - // retrieve length even though we don't need it to workaround bug in chrome cmd buffer - // param validation. - GrGLsizei length = GR_GL_INIT_ZERO; - GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, - &length, (char*)log.get())); - GrPrintf(shaderSrc.c_str()); - GrPrintf("\n%s", log.get()); + + // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. + bool checkCompiled = !glCtx.info().isChromium(); +#ifdef SK_DEBUG + checkCompiled = true; +#endif + if (checkCompiled) { + GrGLint compiled = GR_GL_INIT_ZERO; + GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); + + if (!compiled) { + GrGLint infoLen = GR_GL_INIT_ZERO; + GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); + SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger + if (infoLen > 0) { + // retrieve length even though we don't need it to workaround bug in Chromium cmd + // buffer param validation. + GrGLsizei length = GR_GL_INIT_ZERO; + GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, + &length, (char*)log.get())); + GrPrintf(shaderSrc.c_str()); + GrPrintf("\n%s", log.get()); + } + SkDEBUGFAIL("Shader compilation failed!"); + GR_GL_CALL(gli, DeleteShader(shaderId)); + return false; } - SkDEBUGFAIL("Shader compilation failed!"); - GR_GL_CALL(gli, DeleteShader(shaderId)); - return false; - } else if (c_PrintShaders) { + } + if (c_PrintShaders) { GrPrintf(shaderSrc.c_str()); GrPrintf("\n"); } @@ -663,8 +680,6 @@ bool attach_shader(const GrGLInterface* gli, return true; } -} - bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); fragShaderSrc.append(fFSExtensions); @@ -680,7 +695,7 @@ bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { fragShaderSrc.append("void main() {\n"); fragShaderSrc.append(fFSCode); fragShaderSrc.append("}\n"); - if (!attach_shader(fGpu->glInterface(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc)) { + if (!attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc)) { return false; } @@ -851,7 +866,7 @@ GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects( } bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { - const GrGLInterface* glInterface = this->gpu()->glInterface(); + const GrGLContext& glCtx = this->gpu()->glContext(); SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); this->appendDecls(fVSAttrs, &vertShaderSrc); @@ -859,7 +874,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { vertShaderSrc.append("void main() {\n"); vertShaderSrc.append(fVSCode); vertShaderSrc.append("}\n"); - if (!attach_shader(glInterface, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { + if (!attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { return false; } @@ -887,7 +902,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { "\t}\n" "\tEndPrimitive();\n"); geomShaderSrc.append("}\n"); - if (!attach_shader(glInterface, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) { + if (!attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) { return false; } } diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp index ed4b50c49f..96679fcfd5 100644 --- a/src/gpu/gl/GrGLUtil.cpp +++ b/src/gpu/gl/GrGLUtil.cpp @@ -129,6 +129,10 @@ bool GrGLIsMesaFromVersionString(const char* versionString) { return 4 == n; } +bool GrGLIsChromiumFromRendererString(const char* rendererString) { + return 0 == strcmp(rendererString, "Chromium"); +} + GrGLVersion GrGLGetVersionFromString(const char* versionString) { if (NULL == versionString) { SkDEBUGFAIL("NULL GL version string."); diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h index 5bcf2f324c..a4fb0e5dba 100644 --- a/src/gpu/gl/GrGLUtil.h +++ b/src/gpu/gl/GrGLUtil.h @@ -83,6 +83,7 @@ GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString); bool GrGLIsMesaFromVersionString(const char* versionString); GrGLVendor GrGLGetVendorFromString(const char* vendorString); GrGLRenderer GrGLGetRendererFromString(const char* rendererString); +bool GrGLIsChromiumFromRendererString(const char* rendererString); // these variants call glGetString() GrGLBinding GrGLGetBindingInUse(const GrGLInterface*); @@ -91,6 +92,7 @@ GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*); GrGLVendor GrGLGetVendor(const GrGLInterface*); GrGLRenderer GrGLGetRenderer(const GrGLInterface*); + /** * Helpers for glGetError() */ diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 2a0587be11..677e48cb0f 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -31,6 +31,8 @@ public: GrGpuGL(const GrGLContext& ctx, GrContext* context); virtual ~GrGpuGL(); + const GrGLContext& glContext() const { return fGLContext; } + const GrGLInterface* glInterface() const { return fGLContext.interface(); } const GrGLContextInfo& ctxInfo() const { return fGLContext.info(); } GrGLBinding glBinding() const { return fGLContext.info().binding(); } @@ -177,8 +179,6 @@ private: bool hasExtension(const char* ext) const { return fGLContext.info().hasExtension(ext); } - const GrGLContext& glContext() const { return fGLContext; } - static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); class ProgramCache : public ::SkNoncopyable { |