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