From 2eda5b3a65f54105ae3776160373eed5500c515f Mon Sep 17 00:00:00 2001 From: bsalomon Date: Wed, 21 Sep 2016 10:53:24 -0700 Subject: Conditionally insert gl_PointSize into shaders. BUG=chromium:648816 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2358843002 Review-Url: https://codereview.chromium.org/2358843002 --- src/gpu/GrProgramDesc.cpp | 17 ++++++++++------- src/gpu/GrProgramDesc.h | 27 +++++++++++---------------- src/gpu/gl/GrGLGpu.cpp | 17 +++++++++++++---- src/gpu/gl/GrGLGpu.h | 6 ++++-- src/gpu/gl/GrGLGpuProgramCache.cpp | 5 +++-- src/gpu/gl/GrGLPathRendering.cpp | 4 ++-- src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp | 6 ++++-- src/gpu/instanced/GLInstancedRendering.cpp | 2 +- src/gpu/vk/GrVkPipelineState.cpp | 3 ++- 9 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp index c452d34900..cfcdbb59c1 100644 --- a/src/gpu/GrProgramDesc.cpp +++ b/src/gpu/GrProgramDesc.cpp @@ -106,6 +106,7 @@ static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc, bool GrProgramDesc::Build(GrProgramDesc* desc, const GrPrimitiveProcessor& primProc, + bool hasPointSize, const GrPipeline& pipeline, const GrGLSLCaps& glslCaps) { // The descriptor is used as a cache key. Thus when a field of the @@ -171,14 +172,16 @@ bool GrProgramDesc::Build(GrProgramDesc* desc, header->fOutputSwizzle = glslCaps.configOutputSwizzle(rt->config()).asKey(); - if (pipeline.ignoresCoverage()) { - header->fIgnoresCoverage = 1; - } else { - header->fIgnoresCoverage = 0; - } + header->fIgnoresCoverage = pipeline.ignoresCoverage() ? 1 : 0; header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters(); - header->fColorEffectCnt = pipeline.numColorFragmentProcessors(); - header->fCoverageEffectCnt = pipeline.numCoverageFragmentProcessors(); + header->fColorFragmentProcessorCnt = pipeline.numColorFragmentProcessors(); + header->fCoverageFragmentProcessorCnt = pipeline.numCoverageFragmentProcessors(); + // Fail if the client requested more processors than the key can fit. + if (header->fColorFragmentProcessorCnt != pipeline.numColorFragmentProcessors() || + header->fCoverageFragmentProcessorCnt != pipeline.numCoverageFragmentProcessors()) { + return false; + } + header->fHasPointSize = hasPointSize ? 1 : 0; return true; } diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h index 1f5a5819f5..f304ec53e1 100644 --- a/src/gpu/GrProgramDesc.h +++ b/src/gpu/GrProgramDesc.h @@ -28,6 +28,7 @@ public: * on the returned GrProgramDesc. * * @param GrPrimitiveProcessor The geometry + * @param hasPointSize Controls whether the shader will output a point size. * @param GrPipeline The optimized drawstate. The descriptor will represent a program * which this optstate can use to draw with. The optstate contains * general draw information, as well as the specific color, geometry, @@ -38,6 +39,7 @@ public: **/ static bool Build(GrProgramDesc*, const GrPrimitiveProcessor&, + bool hasPointSize, const GrPipeline&, const GrGLSLCaps&); @@ -92,28 +94,21 @@ public: } struct KeyHeader { - // Set to uniquely identify the rt's origin, or 0 if the shader does not require this info. - uint8_t fSurfaceOriginKey; // Set to uniquely identify the sample pattern, or 0 if the shader doesn't use sample // locations. uint8_t fSamplePatternKey; // Set to uniquely idenitify any swizzling of the shader's output color(s). uint8_t fOutputSwizzle; - uint8_t fSnapVerticesToPixelCenters; - int8_t fColorEffectCnt; - int8_t fCoverageEffectCnt; - uint8_t fIgnoresCoverage; + uint8_t fColorFragmentProcessorCnt : 4; + uint8_t fCoverageFragmentProcessorCnt : 4; + // Set to uniquely identify the rt's origin, or 0 if the shader does not require this info. + uint8_t fSurfaceOriginKey : 2; + uint8_t fIgnoresCoverage : 1; + uint8_t fSnapVerticesToPixelCenters : 1; + uint8_t fHasPointSize : 1; + uint8_t fPad : 3; }; - - int numColorEffects() const { - return this->header().fColorEffectCnt; - } - - int numCoverageEffects() const { - return this->header().fCoverageEffectCnt; - } - - int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); } + GR_STATIC_ASSERT(sizeof(KeyHeader) == 4); // This should really only be used internally, base classes should return their own headers const KeyHeader& header() const { return *this->atOffset(); } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 52c7d94424..fcd3270ba2 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2054,8 +2054,10 @@ void GrGLGpu::flushMinSampleShading(float minSampleShading) { } } -bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc) { - SkAutoTUnref program(fProgramCache->refProgram(this, pipeline, primProc)); +bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, + bool willDrawPoints) { + SkAutoTUnref program(fProgramCache->refProgram(this, pipeline, primProc, + willDrawPoints)); if (!program) { GrCapsDebugf(this->caps(), "Failed to create program!\n"); return false; @@ -2743,11 +2745,18 @@ GrGLenum gPrimitiveType2GLMode[] = { void GrGLGpu::draw(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, - const GrMesh* meshes, + const GrMesh meshes[], int meshCount) { this->handleDirtyContext(); - if (!this->flushGLState(pipeline, primProc)) { + bool hasPoints = false; + for (int i = 0; i < meshCount; ++i) { + if (meshes[i].primitiveType() == kPoints_GrPrimitiveType) { + hasPoints = true; + break; + } + } + if (!this->flushGLState(pipeline, primProc, hasPoints)) { return; } GrPixelLocalStorageState plsState = primProc.getPixelLocalStorageState(); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 62803ee84c..b23be3d9a2 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -230,7 +230,8 @@ private: void setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]); // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. - bool flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc); + // willDrawPoints must be true if point primitives will be rendered after setting the GL state. + bool flushGLState(const GrPipeline&, const GrPrimitiveProcessor&, bool willDrawPoints); // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset // an into the index buffer. It does not account for vertices.startIndex() but rather the start @@ -269,7 +270,8 @@ private: ~ProgramCache(); void abandon(); - GrGLProgram* refProgram(const GrGLGpu* gpu, const GrPipeline&, const GrPrimitiveProcessor&); + GrGLProgram* refProgram(const GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&, + bool hasPointSize); private: enum { diff --git a/src/gpu/gl/GrGLGpuProgramCache.cpp b/src/gpu/gl/GrGLGpuProgramCache.cpp index 8dd5d0c29d..260e256dbe 100644 --- a/src/gpu/gl/GrGLGpuProgramCache.cpp +++ b/src/gpu/gl/GrGLGpuProgramCache.cpp @@ -106,14 +106,15 @@ int GrGLGpu::ProgramCache::search(const GrProgramDesc& desc) const { GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu, const GrPipeline& pipeline, - const GrPrimitiveProcessor& primProc) { + const GrPrimitiveProcessor& primProc, + bool isPoints) { #ifdef PROGRAM_CACHE_STATS ++fTotalRequests; #endif // Get GrGLProgramDesc GrProgramDesc desc; - if (!GrProgramDesc::Build(&desc, primProc, pipeline, *gpu->glCaps().glslCaps())) { + if (!GrProgramDesc::Build(&desc, primProc, isPoints, pipeline, *gpu->glCaps().glslCaps())) { GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n"); return nullptr; } diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index 8508cfb99d..cbf2041255 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -149,7 +149,7 @@ void GrGLPathRendering::onDrawPath(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc, const GrStencilSettings& stencilPassSettings, const GrPath* path) { - if (!this->gpu()->flushGLState(pipeline, primProc)) { + if (!this->gpu()->flushGLState(pipeline, primProc, false)) { return; } const GrGLPath* glPath = static_cast(path); @@ -181,7 +181,7 @@ void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline, PathTransformType transformType, int count) { SkDEBUGCODE(verify_floats(transformValues, gXformType2ComponentCount[transformType] * count)); - if (!this->gpu()->flushGLState(pipeline, primProc)) { + if (!this->gpu()->flushGLState(pipeline, primProc, false)) { return; } this->flushPathStencilSettings(stencilPassSettings); diff --git a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp index 4931e0f256..f8302b38fe 100644 --- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp @@ -46,8 +46,10 @@ void GrGLSLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& po posVar.c_str(), fRtAdjustName, fRtAdjustName); } // We could have the GrGeometryProcessor do this, but its just easier to have it performed - // here. If we ever need to set variable pointsize, then we can reinvestigate - this->codeAppend("gl_PointSize = 1.0;"); + // here. If we ever need to set variable pointsize, then we can reinvestigate. + if (this->getProgramBuilder()->desc().header().fHasPointSize) { + this->codeAppend("gl_PointSize = 1.0;"); + } } void GrGLSLVertexBuilder::onFinalize() { diff --git a/src/gpu/instanced/GLInstancedRendering.cpp b/src/gpu/instanced/GLInstancedRendering.cpp index bd014ecca8..dabfe4e02d 100644 --- a/src/gpu/instanced/GLInstancedRendering.cpp +++ b/src/gpu/instanced/GLInstancedRendering.cpp @@ -204,7 +204,7 @@ void GLInstancedRendering::onDraw(const GrPipeline& pipeline, const InstanceProc if (!fDrawIndirectBuffer && !fGLDrawCmdsInfo) { return; // beginFlush was not successful. } - if (!this->glGpu()->flushGLState(pipeline, instProc)) { + if (!this->glGpu()->flushGLState(pipeline, instProc, false)) { return; } diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp index 50250a5ead..73ff62ed98 100644 --- a/src/gpu/vk/GrVkPipelineState.cpp +++ b/src/gpu/vk/GrVkPipelineState.cpp @@ -487,7 +487,8 @@ bool GrVkPipelineState::Desc::Build(Desc* desc, const GrPipeline& pipeline, GrPrimitiveType primitiveType, const GrGLSLCaps& caps) { - if (!INHERITED::Build(desc, primProc, pipeline, caps)) { + if (!INHERITED::Build(desc, primProc, primitiveType == kPoints_GrPrimitiveType, pipeline, + caps)) { return false; } -- cgit v1.2.3