aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-07-27 12:38:35 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-27 19:04:46 +0000
commit49d14e98fe43fdff818e7571c1a61cd5045fedc0 (patch)
tree18d48cd1922c646b6dafa851fbe214c8904aef87 /src
parentf4f6bbfadac327619a3832acad9c8afe06629b55 (diff)
sksl: Add a "sk_Clockwise" built-in
This allows us to identify clockwise-winding triangles, in terms of Skia device space, in all backends and with all render target origins. Bug: skia: Change-Id: I220e1c459e0129d1cc4dee6458ef94277fbedd21 Reviewed-on: https://skia-review.googlesource.com/142662 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrProcessor.h1
-rw-r--r--src/gpu/gl/GrGLGpu.cpp34
-rw-r--r--src/gpu/gl/GrGLGpu.h5
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp7
-rw-r--r--src/gpu/vk/GrVkPipeline.cpp4
-rw-r--r--src/gpu/vk/GrVkPipelineStateBuilder.cpp24
-rw-r--r--src/sksl/README4
-rw-r--r--src/sksl/SkSLCompiler.h1
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.cpp3
-rw-r--r--src/sksl/sksl_frag.inc2
10 files changed, 52 insertions, 33 deletions
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 4afc928da7..5d83ce3ddb 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -71,6 +71,7 @@ public:
kButtCapStrokedCircleGeometryProcessor_ClassID,
kCircleGeometryProcessor_ClassID,
kCircularRRectEffect_ClassID,
+ kClockwiseTestProcessor_ClassID,
kColorMatrixEffect_ClassID,
kColorTableEffect_ClassID,
kComposeOneFragmentProcessor_ClassID,
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 18ff4c670f..e04a40d8ab 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -359,9 +359,9 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
// We don't use face culling.
GL_CALL(Disable(GR_GL_CULL_FACE));
- // We do use separate stencil. Our algorithms don't care which face is front vs. back so
- // just set this to the default for self-consistency.
- GL_CALL(FrontFace(GR_GL_CCW));
+
+ // Setting the front face keeps gl_FrontFacing consistent in device space.
+ fHWFrontFace = GR_GL_NONE;
fHWBufferState[kTexel_GrBufferType].invalidate();
fHWBufferState[kDrawIndirect_GrBufferType].invalidate();
@@ -1704,6 +1704,7 @@ bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc,
fHWProgram->setData(primProc, pipeline);
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget());
+ GrSurfaceOrigin origin = pipeline.proxy()->origin();
GrStencilSettings stencil;
if (pipeline.isStencilEnabled()) {
// TODO: attach stencil and create settings during render target flush.
@@ -1715,16 +1716,16 @@ bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc,
if (pipeline.isScissorEnabled()) {
static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor);
- this->flushScissor(state, glRT->getViewport(), pipeline.proxy()->origin());
+ this->flushScissor(state, glRT->getViewport(), origin);
} else {
this->disableScissor();
}
- this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, pipeline.proxy()->origin());
+ this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, origin);
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled());
// This must come after textures are flushed because a texture may need
// to be msaa-resolved (which will modify bound FBO state).
- this->flushRenderTarget(glRT);
+ this->flushRenderTarget(glRT, origin);
return true;
}
@@ -1856,9 +1857,9 @@ void GrGLGpu::clear(const GrFixedClip& clip, GrColor color,
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
if (clip.scissorEnabled()) {
- this->flushRenderTarget(glRT, origin, clip.scissorRect());
+ this->flushRenderTarget(glRT, origin, &clip.scissorRect());
} else {
- this->flushRenderTarget(glRT);
+ this->flushRenderTarget(glRT, origin);
}
this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
@@ -2121,14 +2122,17 @@ GrGpuTextureCommandBuffer* GrGLGpu::createCommandBuffer(GrTexture* texture,
}
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, GrSurfaceOrigin origin,
- const SkIRect& bounds) {
+ const SkIRect* bounds) {
this->flushRenderTargetNoColorWrites(target);
- this->didWriteToSurface(target, origin, &bounds);
-}
-void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target) {
- this->flushRenderTargetNoColorWrites(target);
- this->didWriteToSurface(target, kTopLeft_GrSurfaceOrigin, nullptr);
+ // A triangle is front-facing if it winds clockwise in device space.
+ GrGLenum frontFace = (kBottomLeft_GrSurfaceOrigin == origin) ? GR_GL_CW : GR_GL_CCW;
+ if (frontFace != fHWFrontFace) {
+ GL_CALL(FrontFace(frontFace));
+ fHWFrontFace = frontFace;
+ }
+
+ this->didWriteToSurface(target, origin, bounds);
}
void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target) {
@@ -3360,7 +3364,7 @@ void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencil
}
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget());
- this->flushRenderTarget(glRT);
+ this->flushRenderTarget(glRT, origin);
this->flushProgram(fStencilClipClearProgram);
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 78ae024306..3e6dbaad29 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -341,9 +341,7 @@ private:
// The passed bounds contains the render target's color values that will subsequently be
// written.
- void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
- // This version has an implicit bounds of the entire render target.
- void flushRenderTarget(GrGLRenderTarget*);
+ void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect* bounds = nullptr);
// This version can be used when the render target's colors will not be written.
void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
@@ -560,6 +558,7 @@ private:
GrStencilSettings fHWStencilSettings;
TriState fHWStencilTestEnabled;
+ GrGLenum fHWFrontFace;
TriState fHWWriteToColor;
GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID;
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 85c129f8b0..8a53f88b2c 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -88,11 +88,12 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
gpu->flushColorWrite(false);
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fProxy->priv().peekRenderTarget());
+ GrSurfaceOrigin origin = args.fProxy->origin();
SkISize size = SkISize::Make(rt->width(), rt->height());
- this->setProjectionMatrix(*args.fViewMatrix, size, args.fProxy->origin());
- gpu->flushScissor(*args.fScissor, rt->getViewport(), args.fProxy->origin());
+ this->setProjectionMatrix(*args.fViewMatrix, size, origin);
+ gpu->flushScissor(*args.fScissor, rt->getViewport(), origin);
gpu->flushHWAAState(rt, args.fUseHWAA, true);
- gpu->flushRenderTarget(rt);
+ gpu->flushRenderTarget(rt, origin);
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index 60e7f43259..6cdfc4eff9 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -436,7 +436,9 @@ static void setup_raster_state(const GrPipeline& pipeline,
rasterInfo->polygonMode = caps->wireframeMode() ? VK_POLYGON_MODE_LINE
: VK_POLYGON_MODE_FILL;
rasterInfo->cullMode = VK_CULL_MODE_NONE;
- rasterInfo->frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+ // A triangle is front-facing if it winds clockwise in device space.
+ rasterInfo->frontFace = (kTopLeft_GrSurfaceOrigin == pipeline.proxy()->origin())
+ ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterInfo->depthBiasEnable = VK_FALSE;
rasterInfo->depthBiasConstantFactor = 0.0f;
rasterInfo->depthBiasClamp = 0.0f;
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index 91685c6016..bcccbc0c17 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -204,19 +204,23 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
//////////////////////////////////////////////////////////////////////////////
-uint32_t get_blend_info_key(const GrPipeline& pipeline) {
- GrXferProcessor::BlendInfo blendInfo;
- pipeline.getXferProcessor().getBlendInfo(&blendInfo);
-
- static const uint32_t kBlendWriteShift = 1;
+uint32_t get_pipeline_info_key(const GrPipeline& pipeline) {
static const uint32_t kBlendCoeffShift = 5;
GR_STATIC_ASSERT(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
GR_STATIC_ASSERT(kFirstAdvancedGrBlendEquation - 1 < 4);
- uint32_t key = blendInfo.fWriteColor;
- key |= (blendInfo.fSrcBlend << kBlendWriteShift);
- key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
- key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
+ GrXferProcessor::BlendInfo blendInfo;
+ pipeline.getXferProcessor().getBlendInfo(&blendInfo);
+
+ GrSurfaceOrigin origin = pipeline.proxy()->origin();
+ SkASSERT(0 == origin || 1 == origin);
+
+ uint32_t key;
+ key = blendInfo.fEquation;
+ key = blendInfo.fDstBlend | (key << kBlendCoeffShift);
+ key = blendInfo.fSrcBlend | (key << kBlendCoeffShift);
+ key = (int)blendInfo.fWriteColor | (key << 1);
+ key = origin | (key << 1);
return key;
}
@@ -238,7 +242,7 @@ bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
stencil.genKey(&b);
- b.add32(get_blend_info_key(pipeline));
+ b.add32(get_pipeline_info_key(pipeline));
b.add32((uint32_t)primitiveType);
diff --git a/src/sksl/README b/src/sksl/README
index bb2dd05396..dd0af9825f 100644
--- a/src/sksl/README
+++ b/src/sksl/README
@@ -45,6 +45,8 @@ Differences from GLSL
* use sk_InstanceID instead of gl_InstanceID
* the fragment coordinate is sk_FragCoord, and is always relative to the upper
left.
+* use sk_Clockwise instead of gl_FrontFacing. This is always relative to an
+ upper left origin.
* you do not need to include ".0" to make a number a float (meaning that
"float2(x, y) * 4" is perfectly legal in SkSL, unlike GLSL where it would
often have to be expressed "float2(x, y) * 4.0". There is no performance
@@ -149,4 +151,4 @@ Creating a new .fp file
7. At this point you can reference the new fragment processor from within Skia.
Once you have done this initial setup, simply re-build Skia to pick up any
-changes to the .fp file. \ No newline at end of file
+changes to the .fp file.
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index b55bf405bd..c840bd800f 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -27,6 +27,7 @@
#define SK_OUT_BUILTIN 10007
#define SK_LASTFRAGCOLOR_BUILTIN 10008
#define SK_FRAGCOORD_BUILTIN 15
+#define SK_CLOCKWISE_BUILTIN 17
#define SK_VERTEXID_BUILTIN 42
#define SK_INSTANCEID_BUILTIN 43
#define SK_CLIPDISTANCE_BUILTIN 3
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 3c697d8e4b..d08c9135e1 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -689,6 +689,9 @@ void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
case SK_FRAGCOORD_BUILTIN:
this->writeFragCoord();
break;
+ case SK_CLOCKWISE_BUILTIN:
+ this->write("gl_FrontFacing");
+ break;
case SK_VERTEXID_BUILTIN:
this->write("gl_VertexID");
break;
diff --git a/src/sksl/sksl_frag.inc b/src/sksl/sksl_frag.inc
index 429d05a73e..202747a815 100644
--- a/src/sksl/sksl_frag.inc
+++ b/src/sksl/sksl_frag.inc
@@ -2,7 +2,9 @@ STRINGIFY(
// defines built-in interfaces supported by SkiaSL fragment shaders
+// See "enum SpvBuiltIn_" in ./spirv.h
layout(builtin=15) in float4 sk_FragCoord;
+layout(builtin=17) in bool sk_Clockwise; // Similar to gl_FrontFacing, but defined in device space.
layout(builtin=3) float sk_ClipDistance[1];
// 9999 is a temporary value that causes us to ignore these declarations beyond