OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "GrGLGpu.h" | 9 #include "GrGLGpu.h" |
10 #include "GrGLStencilAttachment.h" | 10 #include "GrGLStencilAttachment.h" |
11 #include "GrGLTextureRenderTarget.h" | 11 #include "GrGLTextureRenderTarget.h" |
12 #include "GrGpuResourcePriv.h" | 12 #include "GrGpuResourcePriv.h" |
13 #include "GrPipeline.h" | 13 #include "GrPipeline.h" |
14 #include "GrRenderTargetPriv.h" | 14 #include "GrRenderTargetPriv.h" |
15 #include "GrSurfacePriv.h" | 15 #include "GrSurfacePriv.h" |
16 #include "GrTemplates.h" | 16 #include "GrTemplates.h" |
17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.h" |
18 #include "GrTypes.h" | 18 #include "GrTypes.h" |
19 #include "GrVertices.h" | 19 #include "GrVertices.h" |
| 20 #include "builders/GrGLShaderStringBuilder.h" |
20 #include "SkStrokeRec.h" | 21 #include "SkStrokeRec.h" |
21 #include "SkTemplates.h" | 22 #include "SkTemplates.h" |
22 | 23 |
23 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) | 24 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
24 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) | 25 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) |
25 | 26 |
26 #define SKIP_CACHE_CHECK true | 27 #define SKIP_CACHE_CHECK true |
27 | 28 |
28 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR | 29 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR |
29 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) | 30 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 194 |
194 fLastSuccessfulStencilFmtIdx = 0; | 195 fLastSuccessfulStencilFmtIdx = 0; |
195 fHWProgramID = 0; | 196 fHWProgramID = 0; |
196 fTempSrcFBOID = 0; | 197 fTempSrcFBOID = 0; |
197 fTempDstFBOID = 0; | 198 fTempDstFBOID = 0; |
198 fStencilClearFBOID = 0; | 199 fStencilClearFBOID = 0; |
199 | 200 |
200 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 201 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
201 fPathRendering.reset(new GrGLPathRendering(this)); | 202 fPathRendering.reset(new GrGLPathRendering(this)); |
202 } | 203 } |
| 204 |
| 205 this->createCopyProgram(); |
203 } | 206 } |
204 | 207 |
205 GrGLGpu::~GrGLGpu() { | 208 GrGLGpu::~GrGLGpu() { |
206 if (0 != fHWProgramID) { | 209 if (0 != fHWProgramID) { |
207 // detach the current program so there is no confusion on OpenGL's part | 210 // detach the current program so there is no confusion on OpenGL's part |
208 // that we want it to be deleted | 211 // that we want it to be deleted |
209 SkASSERT(fHWProgramID == fCurrentProgram->programID()); | |
210 GL_CALL(UseProgram(0)); | 212 GL_CALL(UseProgram(0)); |
211 } | 213 } |
212 | 214 |
213 if (0 != fTempSrcFBOID) { | 215 if (0 != fTempSrcFBOID) { |
214 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); | 216 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); |
215 } | 217 } |
216 if (0 != fTempDstFBOID) { | 218 if (0 != fTempDstFBOID) { |
217 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); | 219 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); |
218 } | 220 } |
219 if (0 != fStencilClearFBOID) { | 221 if (0 != fStencilClearFBOID) { |
220 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); | 222 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
221 } | 223 } |
222 | 224 |
| 225 if (0 != fCopyProgram.fArrayBuffer) { |
| 226 GL_CALL(DeleteBuffers(1, &fCopyProgram.fArrayBuffer)); |
| 227 } |
| 228 |
| 229 if (0 != fCopyProgram.fProgram) { |
| 230 GL_CALL(DeleteProgram(fCopyProgram.fProgram)); |
| 231 } |
| 232 |
223 delete fProgramCache; | 233 delete fProgramCache; |
224 } | 234 } |
225 | 235 |
226 void GrGLGpu::contextAbandoned() { | 236 void GrGLGpu::contextAbandoned() { |
227 INHERITED::contextAbandoned(); | 237 INHERITED::contextAbandoned(); |
228 fProgramCache->abandon(); | 238 fProgramCache->abandon(); |
229 fHWProgramID = 0; | 239 fHWProgramID = 0; |
230 fTempSrcFBOID = 0; | 240 fTempSrcFBOID = 0; |
231 fTempDstFBOID = 0; | 241 fTempDstFBOID = 0; |
232 fStencilClearFBOID = 0; | 242 fStencilClearFBOID = 0; |
| 243 fCopyProgram.fArrayBuffer = 0; |
| 244 fCopyProgram.fProgram = 0; |
233 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 245 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
234 this->glPathRendering()->abandonGpuResources(); | 246 this->glPathRendering()->abandonGpuResources(); |
235 } | 247 } |
236 } | 248 } |
237 | 249 |
238 /////////////////////////////////////////////////////////////////////////////// | 250 /////////////////////////////////////////////////////////////////////////////// |
239 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, | 251 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, |
240 GrPixelConfig surfaceConfig) co
nst { | 252 GrPixelConfig surfaceConfig) co
nst { |
241 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { | 253 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { |
242 return kBGRA_8888_GrPixelConfig; | 254 return kBGRA_8888_GrPixelConfig; |
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 | 1422 |
1411 bool GrGLGpu::flushGLState(const DrawArgs& args) { | 1423 bool GrGLGpu::flushGLState(const DrawArgs& args) { |
1412 GrXferProcessor::BlendInfo blendInfo; | 1424 GrXferProcessor::BlendInfo blendInfo; |
1413 const GrPipeline& pipeline = *args.fPipeline; | 1425 const GrPipeline& pipeline = *args.fPipeline; |
1414 args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo); | 1426 args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo); |
1415 | 1427 |
1416 this->flushDither(pipeline.isDitherState()); | 1428 this->flushDither(pipeline.isDitherState()); |
1417 this->flushColorWrite(blendInfo.fWriteColor); | 1429 this->flushColorWrite(blendInfo.fWriteColor); |
1418 this->flushDrawFace(pipeline.getDrawFace()); | 1430 this->flushDrawFace(pipeline.getDrawFace()); |
1419 | 1431 |
1420 fCurrentProgram.reset(fProgramCache->getProgram(args)); | 1432 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(args)); |
1421 if (NULL == fCurrentProgram.get()) { | 1433 if (!program) { |
1422 GrContextDebugf(this->getContext(), "Failed to create program!\n"); | 1434 GrContextDebugf(this->getContext(), "Failed to create program!\n"); |
1423 return false; | 1435 return false; |
1424 } | 1436 } |
1425 | 1437 |
1426 fCurrentProgram.get()->ref(); | 1438 GrGLuint programID = program->programID(); |
1427 | |
1428 GrGLuint programID = fCurrentProgram->programID(); | |
1429 if (fHWProgramID != programID) { | 1439 if (fHWProgramID != programID) { |
1430 GL_CALL(UseProgram(programID)); | 1440 GL_CALL(UseProgram(programID)); |
1431 fHWProgramID = programID; | 1441 fHWProgramID = programID; |
1432 } | 1442 } |
1433 | 1443 |
1434 if (blendInfo.fWriteColor) { | 1444 if (blendInfo.fWriteColor) { |
1435 this->flushBlend(blendInfo); | 1445 this->flushBlend(blendInfo); |
1436 } | 1446 } |
1437 | 1447 |
1438 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); | 1448 program->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker); |
1439 | 1449 |
1440 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 1450 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
1441 this->flushStencil(pipeline.getStencil()); | 1451 this->flushStencil(pipeline.getStencil()); |
1442 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 1452 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
1443 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); | 1453 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); |
1444 | 1454 |
1445 // This must come after textures are flushed because a texture may need | 1455 // This must come after textures are flushed because a texture may need |
1446 // to be msaa-resolved (which will modify bound FBO state). | 1456 // to be msaa-resolved (which will modify bound FBO state). |
1447 this->flushRenderTarget(glRT, NULL); | 1457 this->flushRenderTarget(glRT, NULL); |
1448 | 1458 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 | 1493 |
1484 uint32_t usedAttribArraysMask = 0; | 1494 uint32_t usedAttribArraysMask = 0; |
1485 size_t offset = 0; | 1495 size_t offset = 0; |
1486 | 1496 |
1487 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { | 1497 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { |
1488 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); | 1498 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); |
1489 usedAttribArraysMask |= (1 << attribIndex); | 1499 usedAttribArraysMask |= (1 << attribIndex); |
1490 GrVertexAttribType attribType = attrib.fType; | 1500 GrVertexAttribType attribType = attrib.fType; |
1491 attribState->set(this, | 1501 attribState->set(this, |
1492 attribIndex, | 1502 attribIndex, |
1493 vbuf, | 1503 vbuf->bufferID(), |
1494 GrGLAttribTypeToLayout(attribType).fCount, | 1504 GrGLAttribTypeToLayout(attribType).fCount, |
1495 GrGLAttribTypeToLayout(attribType).fType, | 1505 GrGLAttribTypeToLayout(attribType).fType, |
1496 GrGLAttribTypeToLayout(attribType).fNormalized, | 1506 GrGLAttribTypeToLayout(attribType).fNormalized, |
1497 stride, | 1507 stride, |
1498 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o
ffset)); | 1508 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o
ffset)); |
1499 offset += attrib.fOffset; | 1509 offset += attrib.fOffset; |
1500 } | 1510 } |
1501 attribState->disableUnusedArrays(this, usedAttribArraysMask); | 1511 attribState->disableUnusedArrays(this, usedAttribArraysMask); |
1502 } | 1512 } |
1503 } | 1513 } |
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2611 | 2621 |
2612 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { | 2622 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { |
2613 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2623 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
2614 GR_GL_COLOR_ATTACHMENT0
, | 2624 GR_GL_COLOR_ATTACHMENT0
, |
2615 GR_GL_TEXTURE_2D, | 2625 GR_GL_TEXTURE_2D, |
2616 0, | 2626 0, |
2617 0)); | 2627 0)); |
2618 } | 2628 } |
2619 | 2629 |
2620 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ | 2630 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ |
2621 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are | 2631 // If the src is a texture, we can implement the blit as a draw assuming the
config is |
| 2632 // renderable. |
| 2633 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals
e)) { |
| 2634 desc->fOrigin = kDefault_GrSurfaceOrigin; |
| 2635 desc->fFlags = kRenderTarget_GrSurfaceFlag; |
| 2636 desc->fConfig = src->config(); |
| 2637 return true; |
| 2638 } |
| 2639 |
| 2640 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither
are |
2622 // possible and we return false to fallback to creating a render target dst
for render-to- | 2641 // possible and we return false to fallback to creating a render target dst
for render-to- |
2623 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo | 2642 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo |
2624 // creation. It isn't clear that avoiding temporary fbo creation is actually
optimal. | 2643 // creation. It isn't clear that avoiding temporary fbo creation is actually
optimal. |
2625 | 2644 |
2626 // Check for format issues with glCopyTexSubImage2D | 2645 // Check for format issues with glCopyTexSubImage2D |
2627 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna
lFormat() && | 2646 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna
lFormat() && |
2628 kBGRA_8888_GrPixelConfig == src->config()) { | 2647 kBGRA_8888_GrPixelConfig == src->config()) { |
2629 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be
used with fbo blit | 2648 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be
used with fbo blit |
2630 // then we set up for that, otherwise fail. | 2649 // then we set up for that, otherwise fail. |
2631 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { | 2650 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { |
(...skipping 25 matching lines...) Expand all Loading... |
2657 desc->fConfig = src->config(); | 2676 desc->fConfig = src->config(); |
2658 desc->fOrigin = src->origin(); | 2677 desc->fOrigin = src->origin(); |
2659 desc->fFlags = kNone_GrSurfaceFlags; | 2678 desc->fFlags = kNone_GrSurfaceFlags; |
2660 return true; | 2679 return true; |
2661 } | 2680 } |
2662 | 2681 |
2663 bool GrGLGpu::copySurface(GrSurface* dst, | 2682 bool GrGLGpu::copySurface(GrSurface* dst, |
2664 GrSurface* src, | 2683 GrSurface* src, |
2665 const SkIRect& srcRect, | 2684 const SkIRect& srcRect, |
2666 const SkIPoint& dstPoint) { | 2685 const SkIPoint& dstPoint) { |
2667 bool copied = false; | 2686 if (src->asTexture() && dst->asRenderTarget()) { |
| 2687 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
| 2688 return true; |
| 2689 } |
| 2690 |
2668 if (can_copy_texsubimage(dst, src, this)) { | 2691 if (can_copy_texsubimage(dst, src, this)) { |
2669 GrGLuint srcFBO; | 2692 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
2670 GrGLIRect srcVP; | 2693 return true; |
2671 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem
pFBOTarget); | 2694 } |
2672 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 2695 |
2673 SkASSERT(dstTex); | 2696 if (can_blit_framebuffer(dst, src, this)) { |
2674 // We modified the bound FBO | 2697 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
2675 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 2698 } |
2676 GrGLIRect srcGLRect; | 2699 |
2677 srcGLRect.setRelativeTo(srcVP, | 2700 return false; |
2678 srcRect.fLeft, | 2701 } |
2679 srcRect.fTop, | 2702 |
2680 srcRect.width(), | 2703 |
2681 srcRect.height(), | 2704 void GrGLGpu::createCopyProgram() { |
2682 src->origin()); | 2705 const char* version = GrGetGLSLVersionDecl(this->ctxInfo()); |
2683 | 2706 |
2684 this->setScratchTextureUnit(); | 2707 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T
ypeModifier); |
2685 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | 2708 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, |
2686 GrGLint dstY; | 2709 GrShaderVar::kUniform_TypeModifier); |
2687 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | 2710 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform
_TypeModifier); |
2688 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | 2711 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo
rm_TypeModifier); |
2689 } else { | 2712 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying
Out_TypeModifier); |
2690 dstY = dstPoint.fY; | 2713 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T
ypeModifier); |
| 2714 |
| 2715 SkString vshaderTxt(version); |
| 2716 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2717 vshaderTxt.append(";"); |
| 2718 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2719 vshaderTxt.append(";"); |
| 2720 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2721 vshaderTxt.append(";"); |
| 2722 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2723 vshaderTxt.append(";"); |
| 2724 |
| 2725 vshaderTxt.append( |
| 2726 "// Copy Program VS\n" |
| 2727 "void main() {" |
| 2728 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" |
| 2729 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
| 2730 " gl_Position.zw = vec2(0, 1);" |
| 2731 "}" |
| 2732 ); |
| 2733 |
| 2734 SkString fshaderTxt(version); |
| 2735 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, this->g
lStandard(), |
| 2736 &fshaderTxt); |
| 2737 vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier); |
| 2738 vTexCoord.appendDecl(this->ctxInfo(), &fshaderTxt); |
| 2739 fshaderTxt.append(";"); |
| 2740 uTexture.appendDecl(this->ctxInfo(), &fshaderTxt); |
| 2741 fshaderTxt.append(";"); |
| 2742 const char* fsOutName; |
| 2743 if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) { |
| 2744 oFragColor.appendDecl(this->ctxInfo(), &fshaderTxt); |
| 2745 fshaderTxt.append(";"); |
| 2746 fsOutName = oFragColor.c_str(); |
| 2747 } else { |
| 2748 fsOutName = "gl_FragColor"; |
| 2749 } |
| 2750 fshaderTxt.appendf( |
| 2751 "// Copy Program FS\n" |
| 2752 "void main() {" |
| 2753 " %s = %s(u_texture, v_texCoord);" |
| 2754 "}", |
| 2755 fsOutName, |
| 2756 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) |
| 2757 ); |
| 2758 |
| 2759 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); |
| 2760 const char* str; |
| 2761 GrGLint length; |
| 2762 |
| 2763 str = vshaderTxt.c_str(); |
| 2764 length = SkToInt(vshaderTxt.size()); |
| 2765 GrGLuint vshader = GrGLCompileAndAttachShader(fGLContext, fCopyProgram.fProg
ram, |
| 2766 GR_GL_VERTEX_SHADER, &str, &le
ngth, 1, &fStats); |
| 2767 |
| 2768 str = fshaderTxt.c_str(); |
| 2769 length = SkToInt(fshaderTxt.size()); |
| 2770 GrGLuint fshader = GrGLCompileAndAttachShader(fGLContext, fCopyProgram.fProg
ram, |
| 2771 GR_GL_FRAGMENT_SHADER, &str, &
length, 1, &fStats); |
| 2772 |
| 2773 GL_CALL(LinkProgram(fCopyProgram.fProgram)); |
| 2774 |
| 2775 GL_CALL_RET(fCopyProgram.fTextureUniform, GetUniformLocation(fCopyProgram.fP
rogram, |
| 2776 "u_texture")); |
| 2777 GL_CALL_RET(fCopyProgram.fPosXformUniform, GetUniformLocation(fCopyProgram.f
Program, |
| 2778 "u_posXform"))
; |
| 2779 GL_CALL_RET(fCopyProgram.fTexCoordXformUniform, GetUniformLocation(fCopyProg
ram.fProgram, |
| 2780 "u_texCoo
rdXform")); |
| 2781 |
| 2782 GL_CALL(BindAttribLocation(fCopyProgram.fProgram, 0, "a_vertex")); |
| 2783 |
| 2784 GL_CALL(DeleteShader(vshader)); |
| 2785 GL_CALL(DeleteShader(fshader)); |
| 2786 |
| 2787 GL_CALL(GenBuffers(1, &fCopyProgram.fArrayBuffer)); |
| 2788 fHWGeometryState.setVertexBufferID(this, fCopyProgram.fArrayBuffer); |
| 2789 static const GrGLfloat vdata[] = { |
| 2790 0, 0, |
| 2791 0, 1, |
| 2792 1, 0, |
| 2793 1, 1 |
| 2794 }; |
| 2795 GL_ALLOC_CALL(this->glInterface(), |
| 2796 BufferData(GR_GL_ARRAY_BUFFER, |
| 2797 (GrGLsizeiptr) sizeof(vdata), |
| 2798 vdata, // data ptr |
| 2799 GR_GL_STATIC_DRAW)); |
| 2800 } |
| 2801 |
| 2802 void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, |
| 2803 GrSurface* src, |
| 2804 const SkIRect& srcRect, |
| 2805 const SkIPoint& dstPoint) { |
| 2806 int w = srcRect.width(); |
| 2807 int h = srcRect.height(); |
| 2808 |
| 2809 GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture()); |
| 2810 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_Fil
terMode); |
| 2811 this->bindTexture(0, params, srcTex); |
| 2812 |
| 2813 GrGLRenderTarget* dstRT = static_cast<GrGLRenderTarget*>(dst->asRenderTarget
()); |
| 2814 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h); |
| 2815 this->flushRenderTarget(dstRT, &dstRect); |
| 2816 |
| 2817 GL_CALL(UseProgram(fCopyProgram.fProgram)); |
| 2818 fHWProgramID = fCopyProgram.fProgram; |
| 2819 |
| 2820 fHWGeometryState.setVertexArrayID(this, 0); |
| 2821 |
| 2822 GrGLAttribArrayState* attribs = |
| 2823 fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgram.fArrayBuffe
r); |
| 2824 attribs->set(this, 0, fCopyProgram.fArrayBuffer, 2, GR_GL_FLOAT, false, |
| 2825 2 * sizeof(GrGLfloat), 0); |
| 2826 |
| 2827 |
| 2828 // dst rect edges in NDC (-1 to 1) |
| 2829 int dw = dst->width(); |
| 2830 int dh = dst->height(); |
| 2831 GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f; |
| 2832 GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f; |
| 2833 GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f; |
| 2834 GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f; |
| 2835 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
| 2836 dy0 = -dy0; |
| 2837 dy1 = -dy1; |
| 2838 } |
| 2839 |
| 2840 // src rect edges in normalized texture space (0 to 1) |
| 2841 int sw = src->width(); |
| 2842 int sh = src->height(); |
| 2843 GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft / sw; |
| 2844 GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w) / sw; |
| 2845 GrGLfloat sy0 = (GrGLfloat)srcRect.fTop / sh; |
| 2846 GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h) / sh; |
| 2847 if (kBottomLeft_GrSurfaceOrigin == src->origin()) { |
| 2848 sy0 = 1.f - sy0; |
| 2849 sy1 = 1.f - sy1; |
| 2850 } |
| 2851 |
| 2852 GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0,
dy0)); |
| 2853 GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0,
sx0, sy0)); |
| 2854 GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0)); |
| 2855 |
| 2856 GrXferProcessor::BlendInfo blendInfo; |
| 2857 blendInfo.reset(); |
| 2858 this->flushBlend(blendInfo); |
| 2859 this->flushColorWrite(true); |
| 2860 this->flushDither(false); |
| 2861 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
| 2862 this->flushHWAAState(dstRT, false); |
| 2863 this->disableScissor(); |
| 2864 GrStencilSettings stencil; |
| 2865 stencil.setDisabled(); |
| 2866 this->flushStencil(stencil); |
| 2867 |
| 2868 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); |
| 2869 } |
| 2870 |
| 2871 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, |
| 2872 GrSurface* src, |
| 2873 const SkIRect& srcRect, |
| 2874 const SkIPoint& dstPoint) { |
| 2875 SkASSERT(can_copy_texsubimage(dst, src, this)); |
| 2876 GrGLuint srcFBO; |
| 2877 GrGLIRect srcVP; |
| 2878 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBO
Target); |
| 2879 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
| 2880 SkASSERT(dstTex); |
| 2881 // We modified the bound FBO |
| 2882 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2883 GrGLIRect srcGLRect; |
| 2884 srcGLRect.setRelativeTo(srcVP, |
| 2885 srcRect.fLeft, |
| 2886 srcRect.fTop, |
| 2887 srcRect.width(), |
| 2888 srcRect.height(), |
| 2889 src->origin()); |
| 2890 |
| 2891 this->setScratchTextureUnit(); |
| 2892 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); |
| 2893 GrGLint dstY; |
| 2894 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
| 2895 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); |
| 2896 } else { |
| 2897 dstY = dstPoint.fY; |
| 2898 } |
| 2899 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, |
| 2900 dstPoint.fX, dstY, |
| 2901 srcGLRect.fLeft, srcGLRect.fBottom, |
| 2902 srcGLRect.fWidth, srcGLRect.fHeight)); |
| 2903 if (srcFBO) { |
| 2904 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); |
| 2905 } |
| 2906 } |
| 2907 |
| 2908 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, |
| 2909 GrSurface* src, |
| 2910 const SkIRect& srcRect, |
| 2911 const SkIPoint& dstPoint) { |
| 2912 SkASSERT(can_blit_framebuffer(dst, src, this)); |
| 2913 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
| 2914 srcRect.width(), srcRect.height()); |
| 2915 if (dst == src) { |
| 2916 if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { |
| 2917 return false; |
2691 } | 2918 } |
2692 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | 2919 } |
2693 dstPoint.fX, dstY, | 2920 |
2694 srcGLRect.fLeft, srcGLRect.fBottom, | 2921 GrGLuint dstFBO; |
2695 srcGLRect.fWidth, srcGLRect.fHeight)); | 2922 GrGLuint srcFBO; |
2696 copied = true; | 2923 GrGLIRect dstVP; |
2697 if (srcFBO) { | 2924 GrGLIRect srcVP; |
2698 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); | 2925 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, |
2699 } | 2926 kDst_TempFBOTarget); |
2700 } else if (can_blit_framebuffer(dst, src, this)) { | 2927 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, |
2701 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | 2928 kSrc_TempFBOTarget); |
2702 srcRect.width(), srcRect.height()); | 2929 // We modified the bound FBO |
2703 bool selfOverlap = false; | 2930 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
2704 if (dst == src) { | 2931 GrGLIRect srcGLRect; |
2705 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); | 2932 GrGLIRect dstGLRect; |
2706 } | 2933 srcGLRect.setRelativeTo(srcVP, |
2707 | 2934 srcRect.fLeft, |
2708 if (!selfOverlap) { | 2935 srcRect.fTop, |
2709 GrGLuint dstFBO; | 2936 srcRect.width(), |
2710 GrGLuint srcFBO; | 2937 srcRect.height(), |
2711 GrGLIRect dstVP; | 2938 src->origin()); |
2712 GrGLIRect srcVP; | 2939 dstGLRect.setRelativeTo(dstVP, |
2713 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, | 2940 dstRect.fLeft, |
2714 kDst_TempFBOTarget); | 2941 dstRect.fTop, |
2715 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, | 2942 dstRect.width(), |
2716 kSrc_TempFBOTarget); | 2943 dstRect.height(), |
2717 // We modified the bound FBO | 2944 dst->origin()); |
2718 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 2945 |
2719 GrGLIRect srcGLRect; | 2946 // BlitFrameBuffer respects the scissor, so disable it. |
2720 GrGLIRect dstGLRect; | 2947 this->disableScissor(); |
2721 srcGLRect.setRelativeTo(srcVP, | 2948 |
2722 srcRect.fLeft, | 2949 GrGLint srcY0; |
2723 srcRect.fTop, | 2950 GrGLint srcY1; |
2724 srcRect.width(), | 2951 // Does the blit need to y-mirror or not? |
2725 srcRect.height(), | 2952 if (src->origin() == dst->origin()) { |
2726 src->origin()); | 2953 srcY0 = srcGLRect.fBottom; |
2727 dstGLRect.setRelativeTo(dstVP, | 2954 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; |
2728 dstRect.fLeft, | 2955 } else { |
2729 dstRect.fTop, | 2956 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; |
2730 dstRect.width(), | 2957 srcY1 = srcGLRect.fBottom; |
2731 dstRect.height(), | 2958 } |
2732 dst->origin()); | 2959 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
2733 | 2960 srcY0, |
2734 // BlitFrameBuffer respects the scissor, so disable it. | 2961 srcGLRect.fLeft + srcGLRect.fWidth, |
2735 this->disableScissor(); | 2962 srcY1, |
2736 | 2963 dstGLRect.fLeft, |
2737 GrGLint srcY0; | 2964 dstGLRect.fBottom, |
2738 GrGLint srcY1; | 2965 dstGLRect.fLeft + dstGLRect.fWidth, |
2739 // Does the blit need to y-mirror or not? | 2966 dstGLRect.fBottom + dstGLRect.fHeight, |
2740 if (src->origin() == dst->origin()) { | 2967 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
2741 srcY0 = srcGLRect.fBottom; | 2968 if (dstFBO) { |
2742 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; | 2969 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); |
2743 } else { | 2970 } |
2744 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; | 2971 if (srcFBO) { |
2745 srcY1 = srcGLRect.fBottom; | 2972 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); |
2746 } | 2973 } |
2747 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | 2974 return true; |
2748 srcY0, | |
2749 srcGLRect.fLeft + srcGLRect.fWidth, | |
2750 srcY1, | |
2751 dstGLRect.fLeft, | |
2752 dstGLRect.fBottom, | |
2753 dstGLRect.fLeft + dstGLRect.fWidth, | |
2754 dstGLRect.fBottom + dstGLRect.fHeight, | |
2755 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | |
2756 if (dstFBO) { | |
2757 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); | |
2758 } | |
2759 if (srcFBO) { | |
2760 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); | |
2761 } | |
2762 copied = true; | |
2763 } | |
2764 } | |
2765 return copied; | |
2766 } | |
2767 | |
2768 bool GrGLGpu::canCopySurface(const GrSurface* dst, | |
2769 const GrSurface* src, | |
2770 const SkIRect& srcRect, | |
2771 const SkIPoint& dstPoint) { | |
2772 // This mirrors the logic in onCopySurface. | |
2773 if (can_copy_texsubimage(dst, src, this)) { | |
2774 return true; | |
2775 } | |
2776 if (can_blit_framebuffer(dst, src, this)) { | |
2777 if (dst == src) { | |
2778 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | |
2779 srcRect.width(), srcRect.height(
)); | |
2780 if(!SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { | |
2781 return true; | |
2782 } | |
2783 } else { | |
2784 return true; | |
2785 } | |
2786 } | |
2787 return false; | |
2788 } | 2975 } |
2789 | 2976 |
2790 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { | 2977 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { |
2791 switch (type) { | 2978 switch (type) { |
2792 case kTexture_GrXferBarrierType: { | 2979 case kTexture_GrXferBarrierType: { |
2793 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 2980 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
2794 if (glrt->textureFBOID() != glrt->renderFBOID()) { | 2981 if (glrt->textureFBOID() != glrt->renderFBOID()) { |
2795 // The render target uses separate storage so no need for glText
ureBarrier. | 2982 // The render target uses separate storage so no need for glText
ureBarrier. |
2796 // FIXME: The render target will resolve automatically when its
texture is bound, | 2983 // FIXME: The render target will resolve automatically when its
texture is bound, |
2797 // but we could resolve only the bounds that will be read if we
do it here instead. | 2984 // but we could resolve only the bounds that will be read if we
do it here instead. |
(...skipping 27 matching lines...) Expand all Loading... |
2825 if (this->caps()->gpuTracingSupport()) { | 3012 if (this->caps()->gpuTracingSupport()) { |
2826 #if GR_FORCE_GPU_TRACE_DEBUGGING | 3013 #if GR_FORCE_GPU_TRACE_DEBUGGING |
2827 SkDebugf("Pop trace marker.\n"); | 3014 SkDebugf("Pop trace marker.\n"); |
2828 #else | 3015 #else |
2829 GL_CALL(PopGroupMarker()); | 3016 GL_CALL(PopGroupMarker()); |
2830 #endif | 3017 #endif |
2831 } | 3018 } |
2832 } | 3019 } |
2833 | 3020 |
2834 /////////////////////////////////////////////////////////////////////////////// | 3021 /////////////////////////////////////////////////////////////////////////////// |
2835 | |
2836 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( | 3022 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( |
2837 GrGLGpu* gpu, | 3023 GrGLGpu* gpu, |
2838 const GrGLVertexBuffer* vbuffer, | 3024 const GrGLVertexBuffer* vbuffer, |
2839 const GrGLIndexBuffer* ibuffer)
{ | 3025 const GrGLIndexBuffer* ibuffer)
{ |
2840 SkASSERT(vbuffer); | 3026 SkASSERT(vbuffer); |
| 3027 GrGLuint vbufferID = vbuffer->bufferID(); |
| 3028 GrGLuint* ibufferIDPtr = NULL; |
| 3029 GrGLuint ibufferID; |
| 3030 if (ibuffer) { |
| 3031 ibufferID = ibuffer->bufferID(); |
| 3032 ibufferIDPtr = &ibufferID; |
| 3033 } |
| 3034 return this->internalBind(gpu, vbufferID, ibufferIDPtr); |
| 3035 } |
| 3036 |
| 3037 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBufferToDraw(GrGLGpu
* gpu, |
| 3038 GrGLuin
t vbufferID) { |
| 3039 return this->internalBind(gpu, vbufferID, NULL); |
| 3040 } |
| 3041 |
| 3042 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(GrGLGp
u* gpu, |
| 3043 GrGLui
nt vbufferID, |
| 3044 GrGLui
nt ibufferID) { |
| 3045 return this->internalBind(gpu, vbufferID, &ibufferID); |
| 3046 } |
| 3047 |
| 3048 GrGLAttribArrayState* GrGLGpu::HWGeometryState::internalBind(GrGLGpu* gpu, |
| 3049 GrGLuint vbufferID, |
| 3050 GrGLuint* ibufferID
) { |
2841 GrGLAttribArrayState* attribState; | 3051 GrGLAttribArrayState* attribState; |
2842 | 3052 |
2843 // We use a vertex array if we're on a core profile and the verts are in a V
BO. | 3053 if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) { |
2844 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) { | |
2845 if (!fVBOVertexArray) { | 3054 if (!fVBOVertexArray) { |
2846 GrGLuint arrayID; | 3055 GrGLuint arrayID; |
2847 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); | 3056 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); |
2848 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3057 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2849 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); | 3058 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); |
2850 } | 3059 } |
2851 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, ibuffer); | 3060 if (ibufferID) { |
| 3061 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID); |
| 3062 } else { |
| 3063 attribState = fVBOVertexArray->bind(gpu); |
| 3064 } |
2852 } else { | 3065 } else { |
2853 if (ibuffer) { | 3066 if (ibufferID) { |
2854 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID())
; | 3067 this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID); |
2855 } else { | 3068 } else { |
2856 this->setVertexArrayID(gpu, 0); | 3069 this->setVertexArrayID(gpu, 0); |
2857 } | 3070 } |
2858 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3071 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2859 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3072 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
2860 fDefaultVertexArrayAttribState.resize(attrCount); | 3073 fDefaultVertexArrayAttribState.resize(attrCount); |
2861 } | 3074 } |
2862 attribState = &fDefaultVertexArrayAttribState; | 3075 attribState = &fDefaultVertexArrayAttribState; |
2863 } | 3076 } |
2864 return attribState; | 3077 return attribState; |
2865 } | 3078 } |
OLD | NEW |