diff options
-rw-r--r-- | gyp/gpu.gyp | 3 | ||||
-rw-r--r-- | src/gpu/GrGpuFactory.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 61 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 70 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGLShaders.h | 98 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp (renamed from src/gpu/gl/GrGpuGLShaders.cpp) | 133 | ||||
-rw-r--r-- | tests/GLProgramsTest.cpp | 4 |
8 files changed, 173 insertions, 202 deletions
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp index 621ea023ba..2292236d8b 100644 --- a/gyp/gpu.gyp +++ b/gyp/gpu.gyp @@ -311,8 +311,7 @@ '../src/gpu/gl/GrGLVertexBuffer.h', '../src/gpu/gl/GrGpuGL.cpp', '../src/gpu/gl/GrGpuGL.h', - '../src/gpu/gl/GrGpuGLShaders.cpp', - '../src/gpu/gl/GrGpuGLShaders.h', + '../src/gpu/gl/GrGpuGL_program.cpp', '../src/gpu/gl/debug/GrGLCreateDebugInterface.cpp', '../src/gpu/gl/debug/GrFakeRefObj.h', diff --git a/src/gpu/GrGpuFactory.cpp b/src/gpu/GrGpuFactory.cpp index 319fc42714..4a9bcf6ad2 100644 --- a/src/gpu/GrGpuFactory.cpp +++ b/src/gpu/GrGpuFactory.cpp @@ -12,7 +12,7 @@ #include "gl/GrGLConfig.h" #include "GrGpu.h" -#include "gl/GrGpuGLShaders.h" +#include "gl/GrGpuGL.h" GrGpu* GrGpu::Create(GrEngine engine, GrPlatform3DContext context3D) { @@ -36,7 +36,7 @@ GrGpu* GrGpu::Create(GrEngine engine, GrPlatform3DContext context3D) { } GrGLContextInfo ctxInfo(glInterface); if (ctxInfo.isInitialized()) { - return new GrGpuGLShaders(ctxInfo); + return new GrGpuGL(ctxInfo); } } return NULL; diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index be12b9c7ce..189e876ae5 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -410,7 +410,7 @@ private: void getUniformLocationsAndInitCache(const GrGLContextInfo& gl, CachedData* programData) const; - friend class GrGpuGLShaders; + friend class GrGpuGL; }; #endif diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 62dcb4f21f..b465a883f5 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -207,11 +207,26 @@ GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) { this->initCaps(); + this->createProgramCache(); + +#if 0 + this->programUnitTest(); +#endif + fLastSuccessfulStencilFmtIdx = 0; fCanPreserveUnpremulRoundtrip = kUnknown_CanPreserveUnpremulRoundtrip; } GrGpuGL::~GrGpuGL() { + if (fProgramData && 0 != fHWProgramID) { + // detach the current program so there is no confusion on OpenGL's part + // that we want it to be deleted + GrAssert(fHWProgramID == fProgramData->fProgramID); + GL_CALL(UseProgram(0)); + } + + this->deleteProgramCache(); + // This must be called by before the GrDrawTarget destructor this->releaseGeometry(); // This subclass must do this before the base class destructor runs @@ -283,6 +298,26 @@ void GrGpuGL::initCaps() { fCaps.fMaxRenderTargetSize = GrMin(fCaps.fMaxTextureSize, fCaps.fMaxRenderTargetSize); fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType(); + + // Enable supported shader-related caps + if (kDesktop_GrGLBinding == this->glBinding()) { + fCaps.fDualSourceBlendingSupport = + this->glVersion() >= GR_GL_VER(3,3) || + this->hasExtension("GL_ARB_blend_func_extended"); + fCaps.fShaderDerivativeSupport = true; + // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS + fCaps.fGeometryShaderSupport = + this->glVersion() >= GR_GL_VER(3,2) && + this->glslGeneration() >= k150_GrGLSLGeneration; + } else { + fCaps.fShaderDerivativeSupport = + this->hasExtension("GL_OES_standard_derivatives"); + } + + GR_GL_GetIntegerv(this->glInterface(), + GR_GL_MAX_VERTEX_ATTRIBS, + &fMaxVertexAttribs); + } void GrGpuGL::fillInConfigRenderableTable() { @@ -530,6 +565,32 @@ void GrGpuGL::onResetContext() { if (this->glCaps().packFlipYSupport()) { GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE)); } + + fHWGeometryState.fVertexOffset = ~0; + + // Third party GL code may have left vertex attributes enabled. Some GL + // implementations (osmesa) may read vetex attributes that are not required + // by the current shader. Therefore, we have to ensure that only the + // attributes we require for the current draw are enabled or we may cause an + // invalid read. + + // Disable all vertex layout bits so that next flush will assume all + // optional vertex attributes are disabled. + fHWGeometryState.fVertexLayout = 0; + + // We always use the this attribute and assume it is always enabled. + int posAttrIdx = GrGLProgram::PositionAttributeIdx(); + GL_CALL(EnableVertexAttribArray(posAttrIdx)); + // Disable all other vertex attributes. + for (int va = 0; va < fMaxVertexAttribs; ++va) { + if (va != posAttrIdx) { + GL_CALL(DisableVertexAttribArray(va)); + } + } + + fHWProgramID = 0; + fHWConstAttribColor = GrColor_ILLEGAL; + fHWConstAttribCoverage = GrColor_ILLEGAL; } GrTexture* GrGpuGL::onCreatePlatformTexture(const GrPlatformTextureDesc& desc) { diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index d2557405c9..24d491d63f 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -15,12 +15,14 @@ #include "GrGLContextInfo.h" #include "GrGLIndexBuffer.h" #include "GrGLIRect.h" +#include "GrGLProgram.h" #include "GrGLStencilBuffer.h" #include "GrGLTexture.h" #include "GrGLVertexBuffer.h" class GrGpuGL : public GrGpu { public: + GrGpuGL(const GrGLContextInfo& ctxInfo); virtual ~GrGpuGL(); const GrGLInterface* glInterface() const { @@ -47,8 +49,11 @@ public: virtual bool canPreserveReadWriteUnpremulPixels() SK_OVERRIDE; + virtual void abandonResources() SK_OVERRIDE; + + bool programUnitTest(); + protected: - GrGpuGL(const GrGLContextInfo& ctxInfo); enum TriState { kNo_TriState, @@ -153,6 +158,12 @@ protected: virtual void clearStencil() SK_OVERRIDE; virtual void clearStencilClip(const GrIRect& rect, bool insideClip) SK_OVERRIDE; + virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE; + virtual void setupGeometry(int* startVertex, + int* startIndex, + int vertexCount, + int indexCount) SK_OVERRIDE; + // binds texture unit in GL void setTextureUnit(int unitIdx); @@ -200,6 +211,52 @@ protected: static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); private: + + // for readability of function impls + typedef GrGLProgram::ProgramDesc ProgramDesc; + typedef ProgramDesc::StageDesc StageDesc; + typedef GrGLProgram::CachedData CachedData; + + class ProgramCache; + + void createProgramCache(); + void deleteProgramCache(); + + // sets the texture matrix uniform for currently bound program + void flushTextureMatrix(int stage); + + // sets the texture domain uniform for currently bound program + void flushTextureDomain(int stage); + + // sets the color specified by GrDrawState::setColor() + void flushColor(GrColor color); + + // sets the color specified by GrDrawState::setCoverage() + void flushCoverage(GrColor color); + + // sets the MVP matrix uniform for currently bound program + void flushViewMatrix(); + + // flushes the parameters to two point radial gradient + void flushRadial2(int stage); + + // flushes the parameters for convolution + void flushConvolution(int stage); + + // flushes the normalized texel size + void flushTexelSize(int stage); + + // flushes the color matrix + void flushColorMatrix(); + + static void DeleteProgram(const GrGLInterface* gl, + CachedData* programData); + + void buildProgram(GrPrimitiveType typeBlend, + BlendOptFlags blendOpts, + GrBlendCoeff dstCoeff, + GrCustomStage** customStages); + // Inits GrDrawTarget::Caps, sublcass may enable additional caps. void initCaps(); @@ -251,6 +308,17 @@ private: GrGLContextInfo fGLContextInfo; + // GL program-related state + ProgramCache* fProgramCache; + CachedData* fProgramData; + GrGLuint fHWProgramID; + GrColor fHWConstAttribColor; + GrColor fHWConstAttribCoverage; + GrGLProgram fCurrentProgram; + // If we get rid of fixed function subclass this should move + // to the GLCaps struct in parent class + GrGLint fMaxVertexAttribs; + int fActiveTextureUnitIdx; struct { diff --git a/src/gpu/gl/GrGpuGLShaders.h b/src/gpu/gl/GrGpuGLShaders.h deleted file mode 100644 index c7cdd2b5f5..0000000000 --- a/src/gpu/gl/GrGpuGLShaders.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - - -#ifndef GrGpuGLShaders_DEFINED -#define GrGpuGLShaders_DEFINED - -#include "GrGpuGL.h" -#include "GrGLProgram.h" - -class GrCustomStage; -class GrGpuGLProgram; - -// Programmable OpenGL or OpenGL ES 2.0 -class GrGpuGLShaders : public GrGpuGL { -public: - GrGpuGLShaders(const GrGLContextInfo& ctxInfo); - virtual ~GrGpuGLShaders(); - - virtual void abandonResources() SK_OVERRIDE; - - bool programUnitTest(); - -protected: - // overrides from GrGpu - virtual void onResetContext() SK_OVERRIDE; - virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE; - virtual void setupGeometry(int* startVertex, - int* startIndex, - int vertexCount, - int indexCount) SK_OVERRIDE; - -private: - - // for readability of function impls - typedef GrGLProgram::ProgramDesc ProgramDesc; - typedef ProgramDesc::StageDesc StageDesc; - typedef GrGLProgram::CachedData CachedData; - - class ProgramCache; - - // sets the texture matrix uniform for currently bound program - void flushTextureMatrix(int stage); - - // sets the texture domain uniform for currently bound program - void flushTextureDomain(int stage); - - // sets the color specified by GrDrawState::setColor() - void flushColor(GrColor color); - - // sets the color specified by GrDrawState::setCoverage() - void flushCoverage(GrColor color); - - // sets the MVP matrix uniform for currently bound program - void flushViewMatrix(); - - // flushes the parameters to two point radial gradient - void flushRadial2(int stage); - - // flushes the parameters for convolution - void flushConvolution(int stage); - - // flushes the normalized texel size - void flushTexelSize(int stage); - - // flushes the color matrix - void flushColorMatrix(); - - static void DeleteProgram(const GrGLInterface* gl, - CachedData* programData); - - void buildProgram(GrPrimitiveType typeBlend, - BlendOptFlags blendOpts, - GrBlendCoeff dstCoeff, - GrCustomStage** customStages); - - ProgramCache* fProgramCache; - CachedData* fProgramData; - - GrGLuint fHWProgramID; - GrColor fHWConstAttribColor; - GrColor fHWConstAttribCoverage; - - GrGLProgram fCurrentProgram; - // If we get rid of fixed function subclass this should move - // to the GLCaps struct in parent class - GrGLint fMaxVertexAttribs; - - typedef GrGpuGL INHERITED; -}; - -#endif - diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 802574ceb1..2ac26d5675 100644 --- a/src/gpu/gl/GrGpuGLShaders.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -5,12 +5,11 @@ * found in the LICENSE file. */ -#include "GrGpuGLShaders.h" +#include "GrGpuGL.h" #include "GrBinHashKey.h" #include "effects/GrConvolutionEffect.h" #include "GrCustomStage.h" -#include "GrGLProgram.h" #include "GrGLProgramStage.h" #include "GrGLSL.h" #include "GrGpuVertex.h" @@ -24,7 +23,7 @@ #include "../GrTHashCache.h" -class GrGpuGLShaders::ProgramCache : public ::GrNoncopyable { +class GrGpuGL::ProgramCache : public ::GrNoncopyable { private: class Entry; @@ -69,7 +68,7 @@ public: ~ProgramCache() { for (int i = 0; i < fCount; ++i) { - GrGpuGLShaders::DeleteProgram(fGL.interface(), + GrGpuGL::DeleteProgram(fGL.interface(), &fEntries[i].fProgramData); } } @@ -107,7 +106,7 @@ public: } } fHashCache.remove(entry->fKey, entry); - GrGpuGLShaders::DeleteProgram(fGL.interface(), + GrGpuGL::DeleteProgram(fGL.interface(), &entry->fProgramData); } entry->copyAndTakeOwnership(newEntry); @@ -126,13 +125,7 @@ public: } }; -void GrGpuGLShaders::abandonResources(){ - INHERITED::abandonResources(); - fProgramCache->abandon(); - fHWProgramID = 0; -} - -void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl, +void GrGpuGL::DeleteProgram(const GrGLInterface* gl, CachedData* programData) { GR_GL_CALL(gl, DeleteShader(programData->fVShaderID)); if (programData->fGShaderID) { @@ -145,6 +138,25 @@ void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl, //////////////////////////////////////////////////////////////////////////////// +void GrGpuGL::createProgramCache() { + fProgramData = NULL; + fProgramCache = new ProgramCache(this->glContextInfo()); +} + +void GrGpuGL::deleteProgramCache() { + delete fProgramCache; + fProgramCache = NULL; + fProgramData = NULL; +} + +void GrGpuGL::abandonResources(){ + INHERITED::abandonResources(); + fProgramCache->abandon(); + fHWProgramID = 0; +} + +//////////////////////////////////////////////////////////////////////////////// + #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) namespace { @@ -166,7 +178,7 @@ bool random_bool(GrRandom* r) { } -bool GrGpuGLShaders::programUnitTest() { +bool GrGpuGL::programUnitTest() { GrGLSLGeneration glslGeneration = GrGetGLSLGeneration(this->glBinding(), this->glInterface()); @@ -315,78 +327,7 @@ bool GrGpuGLShaders::programUnitTest() { return true; } -GrGpuGLShaders::GrGpuGLShaders(const GrGLContextInfo& ctxInfo) - : GrGpuGL(ctxInfo) { - - // Enable supported shader-related caps - if (kDesktop_GrGLBinding == this->glBinding()) { - fCaps.fDualSourceBlendingSupport = - this->glVersion() >= GR_GL_VER(3,3) || - this->hasExtension("GL_ARB_blend_func_extended"); - fCaps.fShaderDerivativeSupport = true; - // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS - fCaps.fGeometryShaderSupport = - this->glVersion() >= GR_GL_VER(3,2) && - this->glslGeneration() >= k150_GrGLSLGeneration; - } else { - fCaps.fShaderDerivativeSupport = - this->hasExtension("GL_OES_standard_derivatives"); - } - - GR_GL_GetIntegerv(this->glInterface(), - GR_GL_MAX_VERTEX_ATTRIBS, - &fMaxVertexAttribs); - - fProgramData = NULL; - fProgramCache = new ProgramCache(this->glContextInfo()); - -#if 0 - this->programUnitTest(); -#endif -} - -GrGpuGLShaders::~GrGpuGLShaders() { - - if (fProgramData && 0 != fHWProgramID) { - // detach the current program so there is no confusion on OpenGL's part - // that we want it to be deleted - SkASSERT(fHWProgramID == fProgramData->fProgramID); - GL_CALL(UseProgram(0)); - } - delete fProgramCache; -} - -void GrGpuGLShaders::onResetContext() { - INHERITED::onResetContext(); - - fHWGeometryState.fVertexOffset = ~0; - - // Third party GL code may have left vertex attributes enabled. Some GL - // implementations (osmesa) may read vetex attributes that are not required - // by the current shader. Therefore, we have to ensure that only the - // attributes we require for the current draw are enabled or we may cause an - // invalid read. - - // Disable all vertex layout bits so that next flush will assume all - // optional vertex attributes are disabled. - fHWGeometryState.fVertexLayout = 0; - - // We always use the this attribute and assume it is always enabled. - int posAttrIdx = GrGLProgram::PositionAttributeIdx(); - GL_CALL(EnableVertexAttribArray(posAttrIdx)); - // Disable all other vertex attributes. - for (int va = 0; va < fMaxVertexAttribs; ++va) { - if (va != posAttrIdx) { - GL_CALL(DisableVertexAttribArray(va)); - } - } - - fHWProgramID = 0; - fHWConstAttribColor = GrColor_ILLEGAL; - fHWConstAttribCoverage = GrColor_ILLEGAL; -} - -void GrGpuGLShaders::flushViewMatrix() { +void GrGpuGL::flushViewMatrix() { const GrMatrix& vm = this->getDrawState().getViewMatrix(); if (!fProgramData->fViewMatrix.cheapEqualTo(vm)) { @@ -421,7 +362,7 @@ void GrGpuGLShaders::flushViewMatrix() { } } -void GrGpuGLShaders::flushTextureDomain(int s) { +void GrGpuGL::flushTextureDomain(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni; const GrDrawState& drawState = this->getDrawState(); if (GrGLProgram::kUnusedUniform != uni) { @@ -457,7 +398,7 @@ void GrGpuGLShaders::flushTextureDomain(int s) { } } -void GrGpuGLShaders::flushTextureMatrix(int s) { +void GrGpuGL::flushTextureMatrix(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni; const GrDrawState& drawState = this->getDrawState(); const GrGLTexture* texture = @@ -494,7 +435,7 @@ void GrGpuGLShaders::flushTextureMatrix(int s) { } } -void GrGpuGLShaders::flushRadial2(int s) { +void GrGpuGL::flushRadial2(int s) { const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni; const GrSamplerState& sampler = this->getDrawState().getSampler(s); @@ -528,7 +469,7 @@ void GrGpuGLShaders::flushRadial2(int s) { } } -void GrGpuGLShaders::flushConvolution(int s) { +void GrGpuGL::flushConvolution(int s) { const GrSamplerState& sampler = this->getDrawState().getSampler(s); int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni; if (GrGLProgram::kUnusedUniform != kernelUni) { @@ -554,7 +495,7 @@ void GrGpuGLShaders::flushConvolution(int s) { } } -void GrGpuGLShaders::flushTexelSize(int s) { +void GrGpuGL::flushTexelSize(int s) { const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni; if (GrGLProgram::kUnusedUniform != uni) { const GrGLTexture* texture = @@ -571,7 +512,7 @@ void GrGpuGLShaders::flushTexelSize(int s) { } } -void GrGpuGLShaders::flushColorMatrix() { +void GrGpuGL::flushColorMatrix() { const ProgramDesc& desc = fCurrentProgram.getDesc(); int matrixUni = fProgramData->fUniLocations.fColorMatrixUni; int vecUni = fProgramData->fUniLocations.fColorMatrixVecUni; @@ -602,7 +543,7 @@ static const float ONE_OVER_255 = 1.f / 255.f; GrColorUnpackA(color) * ONE_OVER_255 \ } -void GrGpuGLShaders::flushColor(GrColor color) { +void GrGpuGL::flushColor(GrColor color) { const ProgramDesc& desc = fCurrentProgram.getDesc(); const GrDrawState& drawState = this->getDrawState(); @@ -651,7 +592,7 @@ void GrGpuGLShaders::flushColor(GrColor color) { } } -void GrGpuGLShaders::flushCoverage(GrColor coverage) { +void GrGpuGL::flushCoverage(GrColor coverage) { const ProgramDesc& desc = fCurrentProgram.getDesc(); const GrDrawState& drawState = this->getDrawState(); @@ -693,7 +634,7 @@ void GrGpuGLShaders::flushCoverage(GrColor coverage) { } } -bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { +bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) { if (!flushGLStateCommon(type)) { return false; } @@ -787,7 +728,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { #error "unknown GR_TEXT_SCALAR type" #endif -void GrGpuGLShaders::setupGeometry(int* startVertex, +void GrGpuGL::setupGeometry(int* startVertex, int* startIndex, int vertexCount, int indexCount) { @@ -944,7 +885,7 @@ void setup_custom_stage(GrGLProgram::ProgramDesc::StageDesc* stage, } -void GrGpuGLShaders::buildProgram(GrPrimitiveType type, +void GrGpuGL::buildProgram(GrPrimitiveType type, BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, GrCustomStage** customStages) { diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index 583b80233c..1eb05792a7 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -8,10 +8,10 @@ #include "Test.h" #include "GrContext.h" -#include "gl/GrGpuGLShaders.h" +#include "gl/GrGpuGL.h" static void GLProgramsTest(skiatest::Reporter* reporter, GrContext* context) { - GrGpuGLShaders* shadersGpu = (GrGpuGLShaders*) context->getGpu(); + GrGpuGL* shadersGpu = static_cast<GrGpuGL*>(context->getGpu()); REPORTER_ASSERT(reporter, shadersGpu->programUnitTest()); } |