Index: src/gpu/gl/GrGLGpu.cpp |
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
index 918bee8f89a83d40fc1aa71ed5394196859e6775..5b6ae7cc180fe2023fdb921147cc9a03972ff53a 100644 |
--- a/src/gpu/gl/GrGLGpu.cpp |
+++ b/src/gpu/gl/GrGLGpu.cpp |
@@ -232,8 +232,9 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) |
if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
fPathRendering.reset(new GrGLPathRendering(this)); |
} |
- |
this->createCopyPrograms(); |
+ fWireRectProgram.fProgram = 0; |
+ fWireRectArrayBuffer = 0; |
} |
GrGLGpu::~GrGLGpu() { |
@@ -258,10 +259,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 +286,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(); |
} |
@@ -3016,7 +3028,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; |
@@ -3037,7 +3048,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(";"); |
@@ -3133,6 +3144,160 @@ void GrGLGpu::createCopyPrograms() { |
GR_GL_STATIC_DRAW)); |
} |
+void GrGLGpu::createWireRectProgram() { |
+ 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(); |
+ |
+ // The rect uniform specifies the rectangle in NDC space as a vec4 (left,top,right,bottom). The |
+ // program is used with a vbo containing the unit square. Vertices are computed from the rect |
+ // uniform using the 4 vbo vertices. |
+ SkString vshaderTxt(version); |
+ aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
+ vshaderTxt.append(";"); |
+ uRect.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
+ vshaderTxt.append(";"); |
+ vshaderTxt.append( |
+ "// 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) { |
+ this->handleDirtyContext(); |
+ if (!fWireRectProgram.fProgram) { |
+ this->createWireRectProgram(); |
+ } |
+ |
+ int w = rt->width(); |
+ int h = rt->height(); |
+ |
+ // Compute the edges of the rectangle (top,left,right,bottom) in NDC space. Must consider |
+ // whether the render target is flipped or not. |
+ GrGLfloat edges[4]; |
+ edges[0] = SkIntToScalar(rect.fLeft) + 0.5f; |
+ edges[2] = SkIntToScalar(rect.fRight) - 0.5f; |
+ if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { |
+ edges[1] = h - (SkIntToScalar(rect.fTop) + 0.5f); |
+ edges[3] = h - (SkIntToScalar(rect.fBottom) - 0.5f); |
+ } else { |
+ edges[1] = SkIntToScalar(rect.fTop) + 0.5f; |
+ edges[3] = SkIntToScalar(rect.fBottom) - 0.5f; |
+ } |
+ edges[0] = 2 * edges[0] / w - 1.0f; |
+ edges[1] = 2 * edges[1] / h - 1.0f; |
+ edges[2] = 2 * edges[2] / w - 1.0f; |
+ edges[3] = 2 * edges[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, edges)); |
+ 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, |
@@ -3157,8 +3322,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) |