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
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index c452d34..cfcdbb5 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -106,6 +106,7 @@
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 @@
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 1f5a581..f304ec5 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -28,6 +28,7 @@
* 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 @@
**/
static bool Build(GrProgramDesc*,
const GrPrimitiveProcessor&,
+ bool hasPointSize,
const GrPipeline&,
const GrGLSLCaps&);
@@ -92,28 +94,21 @@
}
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<KeyHeader, kHeaderOffset>(); }
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 52c7d94..fcd3270 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -2054,8 +2054,10 @@
}
}
-bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc) {
- SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc));
+bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc,
+ bool willDrawPoints) {
+ SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc,
+ willDrawPoints));
if (!program) {
GrCapsDebugf(this->caps(), "Failed to create program!\n");
return false;
@@ -2743,11 +2745,18 @@
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 62803ee..b23be3d 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -230,7 +230,8 @@
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 @@
~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 8dd5d0c..260e256 100644
--- a/src/gpu/gl/GrGLGpuProgramCache.cpp
+++ b/src/gpu/gl/GrGLGpuProgramCache.cpp
@@ -106,14 +106,15 @@
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 8508cfb..cbf2041 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -149,7 +149,7 @@
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<const GrGLPath*>(path);
@@ -181,7 +181,7 @@
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 4931e0f..f8302b3 100644
--- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
@@ -46,8 +46,10 @@
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 bd014ec..dabfe4e 100644
--- a/src/gpu/instanced/GLInstancedRendering.cpp
+++ b/src/gpu/instanced/GLInstancedRendering.cpp
@@ -204,7 +204,7 @@
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 50250a5..73ff62e 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -487,7 +487,8 @@
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;
}