Index: src/gpu/gl/GrGLGpu.cpp |
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
index 5eac42028eaa86441b54a85571c825846f7cf851..148db1b15373f8d9b46ebbb139402135a4214e7f 100644 |
--- a/src/gpu/gl/GrGLGpu.cpp |
+++ b/src/gpu/gl/GrGLGpu.cpp |
@@ -232,8 +232,8 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) |
if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
fPathRendering.reset(new GrGLPathRendering(this)); |
} |
- |
this->createCopyPrograms(); |
+ fWireRectProgram.fProgram = 0; |
} |
GrGLGpu::~GrGLGpu() { |
@@ -258,10 +258,19 @@ GrGLGpu::~GrGLGpu() { |
GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); |
} |
} |
+ |
if (0 != fCopyProgramArrayBuffer) { |
GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer)); |
} |
+ if (0 != fWireRectProgram.fProgram) { |
+ GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); |
+ } |
+ |
+ if (0 != fWireRectArrayBuffer) { |
+ GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer)); |
+ } |
+ |
delete fProgramCache; |
} |
@@ -276,6 +285,8 @@ void GrGLGpu::contextAbandoned() { |
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
fCopyPrograms[i].fProgram = 0; |
} |
+ fWireRectProgram.fProgram = 0; |
+ fWireRectArrayBuffer = 0; |
if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
this->glPathRendering()->abandonGpuResources(); |
} |
@@ -2979,7 +2990,6 @@ bool GrGLGpu::onCopySurface(GrSurface* dst, |
return false; |
} |
- |
void GrGLGpu::createCopyPrograms() { |
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
fCopyPrograms[i].fProgram = 0; |
@@ -3000,7 +3010,7 @@ void GrGLGpu::createCopyPrograms() { |
GrShaderVar::kVaryingOut_TypeModifier); |
GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, |
GrShaderVar::kOut_TypeModifier); |
- |
+ |
SkString vshaderTxt(version); |
aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
vshaderTxt.append(";"); |
@@ -3080,7 +3090,6 @@ void GrGLGpu::createCopyPrograms() { |
GL_CALL(DeleteShader(vshader)); |
GL_CALL(DeleteShader(fshader)); |
} |
- |
joshualitt
2015/12/03 14:43:52
I kind of like this space here, but ymmv
bsalomon
2015/12/03 16:25:31
Done.
|
GL_CALL(GenBuffers(1, &fCopyProgramArrayBuffer)); |
fHWGeometryState.setVertexBufferID(this, fCopyProgramArrayBuffer); |
static const GrGLfloat vdata[] = { |
@@ -3096,6 +3105,155 @@ void GrGLGpu::createCopyPrograms() { |
GR_GL_STATIC_DRAW)); |
} |
+void GrGLGpu::createWireRectProgram() { |
joshualitt
2015/12/03 14:43:52
I wonder if we want to create a 'createBackendProg
bsalomon
2015/12/03 16:25:31
I'd prefer to wait on that. I think the !/$ is not
joshualitt
2015/12/03 16:30:14
agreed.
|
+ SkASSERT(!fWireRectProgram.fProgram); |
+ GrGLSLShaderVar uColor("u_color", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier); |
+ GrGLSLShaderVar uRect("u_rect", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier); |
+ GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier); |
+ const char* version = this->glCaps().glslCaps()->versionDeclString(); |
+ |
+ SkString vshaderTxt(version); |
+ aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
+ vshaderTxt.append(";"); |
+ uRect.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
+ vshaderTxt.append(";"); |
+ vshaderTxt.append( |
joshualitt
2015/12/03 14:43:52
A comment on this algorithm would be nice.
bsalomon
2015/12/03 16:25:31
Done.
|
+ "// Wire Rect Program VS\n" |
+ "void main() {" |
+ " gl_Position.x = u_rect.x + a_vertex.x * (u_rect.z - u_rect.x);" |
+ " gl_Position.y = u_rect.y + a_vertex.y * (u_rect.w - u_rect.y);" |
+ " gl_Position.zw = vec2(0, 1);" |
+ "}" |
+ ); |
+ |
+ GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier); |
+ |
+ SkString fshaderTxt(version); |
+ GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, |
+ *this->glCaps().glslCaps(), |
+ &fshaderTxt); |
+ uColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt); |
+ fshaderTxt.append(";"); |
+ const char* fsOutName; |
+ if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) { |
+ oFragColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt); |
+ fshaderTxt.append(";"); |
+ fsOutName = oFragColor.c_str(); |
+ } else { |
+ fsOutName = "gl_FragColor"; |
+ } |
+ fshaderTxt.appendf( |
+ "// Write Rect Program FS\n" |
+ "void main() {" |
+ " %s = %s;" |
+ "}", |
+ fsOutName, |
+ uColor.c_str() |
+ ); |
+ |
+ GL_CALL_RET(fWireRectProgram.fProgram, CreateProgram()); |
+ const char* str; |
+ GrGLint length; |
+ |
+ str = vshaderTxt.c_str(); |
+ length = SkToInt(vshaderTxt.size()); |
+ GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram, |
+ GR_GL_VERTEX_SHADER, &str, &length, 1, |
+ &fStats); |
+ |
+ str = fshaderTxt.c_str(); |
+ length = SkToInt(fshaderTxt.size()); |
+ GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram, |
+ GR_GL_FRAGMENT_SHADER, &str, &length, 1, |
+ &fStats); |
+ |
+ GL_CALL(LinkProgram(fWireRectProgram.fProgram)); |
+ |
+ GL_CALL_RET(fWireRectProgram.fColorUniform, |
+ GetUniformLocation(fWireRectProgram.fProgram, "u_color")); |
+ GL_CALL_RET(fWireRectProgram.fRectUniform, |
+ GetUniformLocation(fWireRectProgram.fProgram, "u_rect")); |
+ GL_CALL(BindAttribLocation(fWireRectProgram.fProgram, 0, "a_vertex")); |
+ |
+ GL_CALL(DeleteShader(vshader)); |
+ GL_CALL(DeleteShader(fshader)); |
+ GL_CALL(GenBuffers(1, &fWireRectArrayBuffer)); |
+ fHWGeometryState.setVertexBufferID(this, fWireRectArrayBuffer); |
+ static const GrGLfloat vdata[] = { |
+ 0, 0, |
+ 0, 1, |
+ 1, 1, |
+ 1, 0, |
+ }; |
+ GL_ALLOC_CALL(this->glInterface(), |
+ BufferData(GR_GL_ARRAY_BUFFER, |
+ (GrGLsizeiptr) sizeof(vdata), |
+ vdata, // data ptr |
+ GR_GL_STATIC_DRAW)); |
+} |
+ |
+void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) { |
joshualitt
2015/12/03 14:43:52
Similar to the above, a 'drawBackend' abstraction
bsalomon
2015/12/03 16:25:31
I'm not sure what there is to abstract... this cal
joshualitt
2015/12/03 16:30:14
Yea, I mean, kind of a backend GrBatch / GrGeometr
|
+ this->handleDirtyContext(); |
+ if (!fWireRectProgram.fProgram) { |
+ this->createWireRectProgram(); |
+ } |
+ |
+ int w = rt->width(); |
+ int h = rt->height(); |
+ |
+ GrGLfloat verts[4]; |
joshualitt
2015/12/03 14:43:52
Could you comment exactly what you are doing here?
|
+ verts[0] = SkIntToScalar(rect.fLeft) + 0.5f; |
+ verts[2] = SkIntToScalar(rect.fRight) - 0.5f; |
+ if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { |
+ verts[1] = h - (SkIntToScalar(rect.fTop) + 0.5f); |
+ verts[3] = h - (SkIntToScalar(rect.fBottom) - 0.5f); |
+ } else { |
+ verts[1] = SkIntToScalar(rect.fTop) + 0.5f; |
+ verts[3] = SkIntToScalar(rect.fBottom) - 0.5f; |
+ } |
+ verts[0] = 2 * verts[0] / w - 1.0f; |
+ verts[1] = 2 * verts[1] / h - 1.0f; |
+ verts[2] = 2 * verts[2] / w - 1.0f; |
+ verts[3] = 2 * verts[3] / h - 1.0f; |
+ |
+ GrGLfloat channels[4]; |
+ static const GrGLfloat scale255 = 1.f / 255.f; |
+ channels[0] = GrColorUnpackR(color) * scale255; |
+ channels[1] = GrColorUnpackG(color) * scale255; |
+ channels[2] = GrColorUnpackB(color) * scale255; |
+ channels[3] = GrColorUnpackA(color) * scale255; |
+ |
+ GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget()); |
+ this->flushRenderTarget(glRT, &rect); |
+ |
+ GL_CALL(UseProgram(fWireRectProgram.fProgram)); |
+ fHWProgramID = fWireRectProgram.fProgram; |
+ |
+ fHWGeometryState.setVertexArrayID(this, 0); |
+ |
+ GrGLAttribArrayState* attribs = |
+ fHWGeometryState.bindArrayAndBufferToDraw(this, fWireRectArrayBuffer); |
+ attribs->set(this, 0, fWireRectArrayBuffer, 2, GR_GL_FLOAT, false, 2 * sizeof(GrGLfloat), 0); |
+ attribs->disableUnusedArrays(this, 0x1); |
+ |
+ GL_CALL(Uniform4fv(fWireRectProgram.fRectUniform, 1, verts)); |
+ GL_CALL(Uniform4fv(fWireRectProgram.fColorUniform, 1, channels)); |
+ |
+ GrXferProcessor::BlendInfo blendInfo; |
+ blendInfo.reset(); |
+ this->flushBlend(blendInfo); |
+ this->flushColorWrite(true); |
+ this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
+ this->flushHWAAState(glRT, false); |
+ this->disableScissor(); |
+ GrStencilSettings stencil; |
+ stencil.setDisabled(); |
+ this->flushStencil(stencil); |
+ |
+ GL_CALL(DrawArrays(GR_GL_LINE_LOOP, 0, 4)); |
+} |
+ |
+ |
void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, |
GrSurface* src, |
const SkIRect& srcRect, |
@@ -3120,8 +3278,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, |
GrGLAttribArrayState* attribs = |
fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgramArrayBuffer); |
- attribs->set(this, 0, fCopyProgramArrayBuffer, 2, GR_GL_FLOAT, false, |
- 2 * sizeof(GrGLfloat), 0); |
+ attribs->set(this, 0, fCopyProgramArrayBuffer, 2, GR_GL_FLOAT, false, 2 * sizeof(GrGLfloat), 0); |
attribs->disableUnusedArrays(this, 0x1); |
// dst rect edges in NDC (-1 to 1) |