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" | |
21 #include "SkStrokeRec.h" | 20 #include "SkStrokeRec.h" |
22 #include "SkTemplates.h" | 21 #include "SkTemplates.h" |
23 | 22 |
24 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) | 23 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
25 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) | 24 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) |
26 | 25 |
27 #define SKIP_CACHE_CHECK true | 26 #define SKIP_CACHE_CHECK true |
28 | 27 |
29 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR | 28 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR |
30 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) | 29 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 193 |
195 fLastSuccessfulStencilFmtIdx = 0; | 194 fLastSuccessfulStencilFmtIdx = 0; |
196 fHWProgramID = 0; | 195 fHWProgramID = 0; |
197 fTempSrcFBOID = 0; | 196 fTempSrcFBOID = 0; |
198 fTempDstFBOID = 0; | 197 fTempDstFBOID = 0; |
199 fStencilClearFBOID = 0; | 198 fStencilClearFBOID = 0; |
200 | 199 |
201 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 200 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
202 fPathRendering.reset(new GrGLPathRendering(this)); | 201 fPathRendering.reset(new GrGLPathRendering(this)); |
203 } | 202 } |
204 | |
205 this->createCopyProgram(); | |
206 } | 203 } |
207 | 204 |
208 GrGLGpu::~GrGLGpu() { | 205 GrGLGpu::~GrGLGpu() { |
209 if (0 != fHWProgramID) { | 206 if (0 != fHWProgramID) { |
210 // detach the current program so there is no confusion on OpenGL's part | 207 // detach the current program so there is no confusion on OpenGL's part |
211 // that we want it to be deleted | 208 // that we want it to be deleted |
| 209 SkASSERT(fHWProgramID == fCurrentProgram->programID()); |
212 GL_CALL(UseProgram(0)); | 210 GL_CALL(UseProgram(0)); |
213 } | 211 } |
214 | 212 |
215 if (0 != fTempSrcFBOID) { | 213 if (0 != fTempSrcFBOID) { |
216 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); | 214 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); |
217 } | 215 } |
218 if (0 != fTempDstFBOID) { | 216 if (0 != fTempDstFBOID) { |
219 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); | 217 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); |
220 } | 218 } |
221 if (0 != fStencilClearFBOID) { | 219 if (0 != fStencilClearFBOID) { |
222 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); | 220 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
223 } | 221 } |
224 | 222 |
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 | |
233 delete fProgramCache; | 223 delete fProgramCache; |
234 } | 224 } |
235 | 225 |
236 void GrGLGpu::contextAbandoned() { | 226 void GrGLGpu::contextAbandoned() { |
237 INHERITED::contextAbandoned(); | 227 INHERITED::contextAbandoned(); |
238 fProgramCache->abandon(); | 228 fProgramCache->abandon(); |
239 fHWProgramID = 0; | 229 fHWProgramID = 0; |
240 fTempSrcFBOID = 0; | 230 fTempSrcFBOID = 0; |
241 fTempDstFBOID = 0; | 231 fTempDstFBOID = 0; |
242 fStencilClearFBOID = 0; | 232 fStencilClearFBOID = 0; |
243 fCopyProgram.fArrayBuffer = 0; | |
244 fCopyProgram.fProgram = 0; | |
245 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 233 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
246 this->glPathRendering()->abandonGpuResources(); | 234 this->glPathRendering()->abandonGpuResources(); |
247 } | 235 } |
248 } | 236 } |
249 | 237 |
250 /////////////////////////////////////////////////////////////////////////////// | 238 /////////////////////////////////////////////////////////////////////////////// |
251 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, | 239 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, |
252 GrPixelConfig surfaceConfig) co
nst { | 240 GrPixelConfig surfaceConfig) co
nst { |
253 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { | 241 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { |
254 return kBGRA_8888_GrPixelConfig; | 242 return kBGRA_8888_GrPixelConfig; |
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 | 1410 |
1423 bool GrGLGpu::flushGLState(const DrawArgs& args) { | 1411 bool GrGLGpu::flushGLState(const DrawArgs& args) { |
1424 GrXferProcessor::BlendInfo blendInfo; | 1412 GrXferProcessor::BlendInfo blendInfo; |
1425 const GrPipeline& pipeline = *args.fPipeline; | 1413 const GrPipeline& pipeline = *args.fPipeline; |
1426 args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo); | 1414 args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo); |
1427 | 1415 |
1428 this->flushDither(pipeline.isDitherState()); | 1416 this->flushDither(pipeline.isDitherState()); |
1429 this->flushColorWrite(blendInfo.fWriteColor); | 1417 this->flushColorWrite(blendInfo.fWriteColor); |
1430 this->flushDrawFace(pipeline.getDrawFace()); | 1418 this->flushDrawFace(pipeline.getDrawFace()); |
1431 | 1419 |
1432 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(args)); | 1420 fCurrentProgram.reset(fProgramCache->getProgram(args)); |
1433 if (!program) { | 1421 if (NULL == fCurrentProgram.get()) { |
1434 GrContextDebugf(this->getContext(), "Failed to create program!\n"); | 1422 GrContextDebugf(this->getContext(), "Failed to create program!\n"); |
1435 return false; | 1423 return false; |
1436 } | 1424 } |
1437 | 1425 |
1438 GrGLuint programID = program->programID(); | 1426 fCurrentProgram.get()->ref(); |
| 1427 |
| 1428 GrGLuint programID = fCurrentProgram->programID(); |
1439 if (fHWProgramID != programID) { | 1429 if (fHWProgramID != programID) { |
1440 GL_CALL(UseProgram(programID)); | 1430 GL_CALL(UseProgram(programID)); |
1441 fHWProgramID = programID; | 1431 fHWProgramID = programID; |
1442 } | 1432 } |
1443 | 1433 |
1444 if (blendInfo.fWriteColor) { | 1434 if (blendInfo.fWriteColor) { |
1445 this->flushBlend(blendInfo); | 1435 this->flushBlend(blendInfo); |
1446 } | 1436 } |
1447 | 1437 |
1448 program->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker); | 1438 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); |
1449 | 1439 |
1450 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 1440 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
1451 this->flushStencil(pipeline.getStencil()); | 1441 this->flushStencil(pipeline.getStencil()); |
1452 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 1442 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
1453 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); | 1443 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); |
1454 | 1444 |
1455 // This must come after textures are flushed because a texture may need | 1445 // This must come after textures are flushed because a texture may need |
1456 // to be msaa-resolved (which will modify bound FBO state). | 1446 // to be msaa-resolved (which will modify bound FBO state). |
1457 this->flushRenderTarget(glRT, NULL); | 1447 this->flushRenderTarget(glRT, NULL); |
1458 | 1448 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 | 1483 |
1494 uint32_t usedAttribArraysMask = 0; | 1484 uint32_t usedAttribArraysMask = 0; |
1495 size_t offset = 0; | 1485 size_t offset = 0; |
1496 | 1486 |
1497 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { | 1487 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { |
1498 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); | 1488 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); |
1499 usedAttribArraysMask |= (1 << attribIndex); | 1489 usedAttribArraysMask |= (1 << attribIndex); |
1500 GrVertexAttribType attribType = attrib.fType; | 1490 GrVertexAttribType attribType = attrib.fType; |
1501 attribState->set(this, | 1491 attribState->set(this, |
1502 attribIndex, | 1492 attribIndex, |
1503 vbuf->bufferID(), | 1493 vbuf, |
1504 GrGLAttribTypeToLayout(attribType).fCount, | 1494 GrGLAttribTypeToLayout(attribType).fCount, |
1505 GrGLAttribTypeToLayout(attribType).fType, | 1495 GrGLAttribTypeToLayout(attribType).fType, |
1506 GrGLAttribTypeToLayout(attribType).fNormalized, | 1496 GrGLAttribTypeToLayout(attribType).fNormalized, |
1507 stride, | 1497 stride, |
1508 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o
ffset)); | 1498 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o
ffset)); |
1509 offset += attrib.fOffset; | 1499 offset += attrib.fOffset; |
1510 } | 1500 } |
1511 attribState->disableUnusedArrays(this, usedAttribArraysMask); | 1501 attribState->disableUnusedArrays(this, usedAttribArraysMask); |
1512 } | 1502 } |
1513 } | 1503 } |
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2621 | 2611 |
2622 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { | 2612 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { |
2623 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2613 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
2624 GR_GL_COLOR_ATTACHMENT0
, | 2614 GR_GL_COLOR_ATTACHMENT0
, |
2625 GR_GL_TEXTURE_2D, | 2615 GR_GL_TEXTURE_2D, |
2626 0, | 2616 0, |
2627 0)); | 2617 0)); |
2628 } | 2618 } |
2629 | 2619 |
2630 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ | 2620 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ |
2631 // If the src is a texture, we can implement the blit as a draw assuming the
config is | 2621 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are |
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 | |
2641 // possible and we return false to fallback to creating a render target dst
for render-to- | 2622 // possible and we return false to fallback to creating a render target dst
for render-to- |
2642 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo | 2623 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo |
2643 // creation. It isn't clear that avoiding temporary fbo creation is actually
optimal. | 2624 // creation. It isn't clear that avoiding temporary fbo creation is actually
optimal. |
2644 | 2625 |
2645 // Check for format issues with glCopyTexSubImage2D | 2626 // Check for format issues with glCopyTexSubImage2D |
2646 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna
lFormat() && | 2627 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna
lFormat() && |
2647 kBGRA_8888_GrPixelConfig == src->config()) { | 2628 kBGRA_8888_GrPixelConfig == src->config()) { |
2648 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be
used with fbo blit | 2629 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be
used with fbo blit |
2649 // then we set up for that, otherwise fail. | 2630 // then we set up for that, otherwise fail. |
2650 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { | 2631 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { |
(...skipping 25 matching lines...) Expand all Loading... |
2676 desc->fConfig = src->config(); | 2657 desc->fConfig = src->config(); |
2677 desc->fOrigin = src->origin(); | 2658 desc->fOrigin = src->origin(); |
2678 desc->fFlags = kNone_GrSurfaceFlags; | 2659 desc->fFlags = kNone_GrSurfaceFlags; |
2679 return true; | 2660 return true; |
2680 } | 2661 } |
2681 | 2662 |
2682 bool GrGLGpu::copySurface(GrSurface* dst, | 2663 bool GrGLGpu::copySurface(GrSurface* dst, |
2683 GrSurface* src, | 2664 GrSurface* src, |
2684 const SkIRect& srcRect, | 2665 const SkIRect& srcRect, |
2685 const SkIPoint& dstPoint) { | 2666 const SkIPoint& dstPoint) { |
2686 if (src->asTexture() && dst->asRenderTarget()) { | 2667 bool copied = false; |
2687 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 2668 if (can_copy_texsubimage(dst, src, this)) { |
| 2669 GrGLuint srcFBO; |
| 2670 GrGLIRect srcVP; |
| 2671 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem
pFBOTarget); |
| 2672 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
| 2673 SkASSERT(dstTex); |
| 2674 // We modified the bound FBO |
| 2675 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2676 GrGLIRect srcGLRect; |
| 2677 srcGLRect.setRelativeTo(srcVP, |
| 2678 srcRect.fLeft, |
| 2679 srcRect.fTop, |
| 2680 srcRect.width(), |
| 2681 srcRect.height(), |
| 2682 src->origin()); |
| 2683 |
| 2684 this->setScratchTextureUnit(); |
| 2685 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); |
| 2686 GrGLint dstY; |
| 2687 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
| 2688 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); |
| 2689 } else { |
| 2690 dstY = dstPoint.fY; |
| 2691 } |
| 2692 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, |
| 2693 dstPoint.fX, dstY, |
| 2694 srcGLRect.fLeft, srcGLRect.fBottom, |
| 2695 srcGLRect.fWidth, srcGLRect.fHeight)); |
| 2696 copied = true; |
| 2697 if (srcFBO) { |
| 2698 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); |
| 2699 } |
| 2700 } else if (can_blit_framebuffer(dst, src, this)) { |
| 2701 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
| 2702 srcRect.width(), srcRect.height()); |
| 2703 bool selfOverlap = false; |
| 2704 if (dst == src) { |
| 2705 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); |
| 2706 } |
| 2707 |
| 2708 if (!selfOverlap) { |
| 2709 GrGLuint dstFBO; |
| 2710 GrGLuint srcFBO; |
| 2711 GrGLIRect dstVP; |
| 2712 GrGLIRect srcVP; |
| 2713 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, |
| 2714 kDst_TempFBOTarget); |
| 2715 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, |
| 2716 kSrc_TempFBOTarget); |
| 2717 // We modified the bound FBO |
| 2718 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2719 GrGLIRect srcGLRect; |
| 2720 GrGLIRect dstGLRect; |
| 2721 srcGLRect.setRelativeTo(srcVP, |
| 2722 srcRect.fLeft, |
| 2723 srcRect.fTop, |
| 2724 srcRect.width(), |
| 2725 srcRect.height(), |
| 2726 src->origin()); |
| 2727 dstGLRect.setRelativeTo(dstVP, |
| 2728 dstRect.fLeft, |
| 2729 dstRect.fTop, |
| 2730 dstRect.width(), |
| 2731 dstRect.height(), |
| 2732 dst->origin()); |
| 2733 |
| 2734 // BlitFrameBuffer respects the scissor, so disable it. |
| 2735 this->disableScissor(); |
| 2736 |
| 2737 GrGLint srcY0; |
| 2738 GrGLint srcY1; |
| 2739 // Does the blit need to y-mirror or not? |
| 2740 if (src->origin() == dst->origin()) { |
| 2741 srcY0 = srcGLRect.fBottom; |
| 2742 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; |
| 2743 } else { |
| 2744 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; |
| 2745 srcY1 = srcGLRect.fBottom; |
| 2746 } |
| 2747 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
| 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)) { |
2688 return true; | 2774 return true; |
2689 } | 2775 } |
2690 | 2776 if (can_blit_framebuffer(dst, src, this)) { |
2691 if (can_copy_texsubimage(dst, src, this)) { | 2777 if (dst == src) { |
2692 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); | 2778 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
2693 return true; | 2779 srcRect.width(), srcRect.height(
)); |
| 2780 if(!SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { |
| 2781 return true; |
| 2782 } |
| 2783 } else { |
| 2784 return true; |
| 2785 } |
2694 } | 2786 } |
2695 | |
2696 if (can_blit_framebuffer(dst, src, this)) { | |
2697 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); | |
2698 } | |
2699 | |
2700 return false; | 2787 return false; |
2701 } | 2788 } |
2702 | 2789 |
2703 | |
2704 void GrGLGpu::createCopyProgram() { | |
2705 const char* version = GrGetGLSLVersionDecl(this->ctxInfo()); | |
2706 | |
2707 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T
ypeModifier); | |
2708 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, | |
2709 GrShaderVar::kUniform_TypeModifier); | |
2710 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform
_TypeModifier); | |
2711 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo
rm_TypeModifier); | |
2712 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying
Out_TypeModifier); | |
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; | |
2918 } | |
2919 } | |
2920 | |
2921 GrGLuint dstFBO; | |
2922 GrGLuint srcFBO; | |
2923 GrGLIRect dstVP; | |
2924 GrGLIRect srcVP; | |
2925 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, | |
2926 kDst_TempFBOTarget); | |
2927 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, | |
2928 kSrc_TempFBOTarget); | |
2929 // We modified the bound FBO | |
2930 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
2931 GrGLIRect srcGLRect; | |
2932 GrGLIRect dstGLRect; | |
2933 srcGLRect.setRelativeTo(srcVP, | |
2934 srcRect.fLeft, | |
2935 srcRect.fTop, | |
2936 srcRect.width(), | |
2937 srcRect.height(), | |
2938 src->origin()); | |
2939 dstGLRect.setRelativeTo(dstVP, | |
2940 dstRect.fLeft, | |
2941 dstRect.fTop, | |
2942 dstRect.width(), | |
2943 dstRect.height(), | |
2944 dst->origin()); | |
2945 | |
2946 // BlitFrameBuffer respects the scissor, so disable it. | |
2947 this->disableScissor(); | |
2948 | |
2949 GrGLint srcY0; | |
2950 GrGLint srcY1; | |
2951 // Does the blit need to y-mirror or not? | |
2952 if (src->origin() == dst->origin()) { | |
2953 srcY0 = srcGLRect.fBottom; | |
2954 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; | |
2955 } else { | |
2956 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; | |
2957 srcY1 = srcGLRect.fBottom; | |
2958 } | |
2959 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | |
2960 srcY0, | |
2961 srcGLRect.fLeft + srcGLRect.fWidth, | |
2962 srcY1, | |
2963 dstGLRect.fLeft, | |
2964 dstGLRect.fBottom, | |
2965 dstGLRect.fLeft + dstGLRect.fWidth, | |
2966 dstGLRect.fBottom + dstGLRect.fHeight, | |
2967 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | |
2968 if (dstFBO) { | |
2969 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); | |
2970 } | |
2971 if (srcFBO) { | |
2972 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); | |
2973 } | |
2974 return true; | |
2975 } | |
2976 | |
2977 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { | 2790 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { |
2978 switch (type) { | 2791 switch (type) { |
2979 case kTexture_GrXferBarrierType: { | 2792 case kTexture_GrXferBarrierType: { |
2980 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 2793 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
2981 if (glrt->textureFBOID() != glrt->renderFBOID()) { | 2794 if (glrt->textureFBOID() != glrt->renderFBOID()) { |
2982 // The render target uses separate storage so no need for glText
ureBarrier. | 2795 // The render target uses separate storage so no need for glText
ureBarrier. |
2983 // FIXME: The render target will resolve automatically when its
texture is bound, | 2796 // FIXME: The render target will resolve automatically when its
texture is bound, |
2984 // but we could resolve only the bounds that will be read if we
do it here instead. | 2797 // but we could resolve only the bounds that will be read if we
do it here instead. |
2985 return; | 2798 return; |
2986 } | 2799 } |
(...skipping 25 matching lines...) Expand all Loading... |
3012 if (this->caps()->gpuTracingSupport()) { | 2825 if (this->caps()->gpuTracingSupport()) { |
3013 #if GR_FORCE_GPU_TRACE_DEBUGGING | 2826 #if GR_FORCE_GPU_TRACE_DEBUGGING |
3014 SkDebugf("Pop trace marker.\n"); | 2827 SkDebugf("Pop trace marker.\n"); |
3015 #else | 2828 #else |
3016 GL_CALL(PopGroupMarker()); | 2829 GL_CALL(PopGroupMarker()); |
3017 #endif | 2830 #endif |
3018 } | 2831 } |
3019 } | 2832 } |
3020 | 2833 |
3021 /////////////////////////////////////////////////////////////////////////////// | 2834 /////////////////////////////////////////////////////////////////////////////// |
| 2835 |
3022 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( | 2836 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( |
3023 GrGLGpu* gpu, | 2837 GrGLGpu* gpu, |
3024 const GrGLVertexBuffer* vbuffer, | 2838 const GrGLVertexBuffer* vbuffer, |
3025 const GrGLIndexBuffer* ibuffer)
{ | 2839 const GrGLIndexBuffer* ibuffer)
{ |
3026 SkASSERT(vbuffer); | 2840 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
) { | |
3051 GrGLAttribArrayState* attribState; | 2841 GrGLAttribArrayState* attribState; |
3052 | 2842 |
3053 if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) { | 2843 // We use a vertex array if we're on a core profile and the verts are in a V
BO. |
| 2844 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) { |
3054 if (!fVBOVertexArray) { | 2845 if (!fVBOVertexArray) { |
3055 GrGLuint arrayID; | 2846 GrGLuint arrayID; |
3056 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); | 2847 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); |
3057 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2848 int attrCount = gpu->glCaps().maxVertexAttributes(); |
3058 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); | 2849 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); |
3059 } | 2850 } |
3060 if (ibufferID) { | 2851 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, ibuffer); |
3061 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID); | |
3062 } else { | |
3063 attribState = fVBOVertexArray->bind(gpu); | |
3064 } | |
3065 } else { | 2852 } else { |
3066 if (ibufferID) { | 2853 if (ibuffer) { |
3067 this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID); | 2854 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID())
; |
3068 } else { | 2855 } else { |
3069 this->setVertexArrayID(gpu, 0); | 2856 this->setVertexArrayID(gpu, 0); |
3070 } | 2857 } |
3071 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2858 int attrCount = gpu->glCaps().maxVertexAttributes(); |
3072 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2859 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
3073 fDefaultVertexArrayAttribState.resize(attrCount); | 2860 fDefaultVertexArrayAttribState.resize(attrCount); |
3074 } | 2861 } |
3075 attribState = &fDefaultVertexArrayAttribState; | 2862 attribState = &fDefaultVertexArrayAttribState; |
3076 } | 2863 } |
3077 return attribState; | 2864 return attribState; |
3078 } | 2865 } |
OLD | NEW |