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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 this); | 181 this); |
181 SkDebugf("------ VENDOR %s\n", vendor); | 182 SkDebugf("------ VENDOR %s\n", vendor); |
182 SkDebugf("------ RENDERER %s\n", renderer); | 183 SkDebugf("------ RENDERER %s\n", renderer); |
183 SkDebugf("------ VERSION %s\n", version); | 184 SkDebugf("------ VERSION %s\n", version); |
184 SkDebugf("------ EXTENSIONS\n"); | 185 SkDebugf("------ EXTENSIONS\n"); |
185 ctx.extensions().print(); | 186 ctx.extensions().print(); |
186 SkDebugf("\n"); | 187 SkDebugf("\n"); |
187 SkDebugf("%s", this->glCaps().dump().c_str()); | 188 SkDebugf("%s", this->glCaps().dump().c_str()); |
188 } | 189 } |
189 | 190 |
191 // Do this early before we start tracking GL state since this binds GL objec ts. | |
192 this->createCopyProgram(); | |
193 | |
190 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); | 194 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); |
191 | 195 |
192 SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVe rtexAttribs); | 196 SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVe rtexAttribs); |
193 | 197 |
194 fLastSuccessfulStencilFmtIdx = 0; | 198 fLastSuccessfulStencilFmtIdx = 0; |
195 fHWProgramID = 0; | 199 fHWProgramID = 0; |
196 fTempSrcFBOID = 0; | 200 fTempSrcFBOID = 0; |
197 fTempDstFBOID = 0; | 201 fTempDstFBOID = 0; |
198 fStencilClearFBOID = 0; | 202 fStencilClearFBOID = 0; |
199 | 203 |
204 this->createCopyProgram(); | |
egdaniel
2015/05/13 19:04:42
you call this twice?
bsalomon
2015/05/15 17:56:31
Done.
| |
200 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 205 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
201 fPathRendering.reset(new GrGLPathRendering(this)); | 206 fPathRendering.reset(new GrGLPathRendering(this)); |
202 } | 207 } |
203 } | 208 } |
204 | 209 |
205 GrGLGpu::~GrGLGpu() { | 210 GrGLGpu::~GrGLGpu() { |
206 if (0 != fHWProgramID) { | 211 if (0 != fHWProgramID) { |
207 // detach the current program so there is no confusion on OpenGL's part | 212 // detach the current program so there is no confusion on OpenGL's part |
208 // that we want it to be deleted | 213 // that we want it to be deleted |
209 SkASSERT(fHWProgramID == fCurrentProgram->programID()); | 214 SkASSERT(fHWProgramID == fCurrentProgram->programID()); |
210 GL_CALL(UseProgram(0)); | 215 GL_CALL(UseProgram(0)); |
211 } | 216 } |
212 | 217 |
213 if (0 != fTempSrcFBOID) { | 218 if (0 != fTempSrcFBOID) { |
214 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); | 219 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); |
215 } | 220 } |
216 if (0 != fTempDstFBOID) { | 221 if (0 != fTempDstFBOID) { |
217 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); | 222 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); |
218 } | 223 } |
219 if (0 != fStencilClearFBOID) { | 224 if (0 != fStencilClearFBOID) { |
220 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); | 225 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
221 } | 226 } |
222 | 227 |
228 if (0 != fCopyProgram.fArrayBuffer) { | |
229 GL_CALL(DeleteBuffers(1, &fCopyProgram.fArrayBuffer)); | |
230 } | |
231 | |
232 if (0 != fCopyProgram.fProgram) { | |
233 GL_CALL(DeleteProgram(fCopyProgram.fProgram)); | |
234 } | |
235 | |
223 delete fProgramCache; | 236 delete fProgramCache; |
224 } | 237 } |
225 | 238 |
226 void GrGLGpu::contextAbandoned() { | 239 void GrGLGpu::contextAbandoned() { |
227 INHERITED::contextAbandoned(); | 240 INHERITED::contextAbandoned(); |
228 fProgramCache->abandon(); | 241 fProgramCache->abandon(); |
229 fHWProgramID = 0; | 242 fHWProgramID = 0; |
230 fTempSrcFBOID = 0; | 243 fTempSrcFBOID = 0; |
231 fTempDstFBOID = 0; | 244 fTempDstFBOID = 0; |
232 fStencilClearFBOID = 0; | 245 fStencilClearFBOID = 0; |
246 fCopyProgram.fArrayBuffer = 0; | |
247 fCopyProgram.fProgram = 0; | |
233 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 248 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
234 this->glPathRendering()->abandonGpuResources(); | 249 this->glPathRendering()->abandonGpuResources(); |
235 } | 250 } |
236 } | 251 } |
237 | 252 |
238 /////////////////////////////////////////////////////////////////////////////// | 253 /////////////////////////////////////////////////////////////////////////////// |
239 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, | 254 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, |
240 GrPixelConfig surfaceConfig) co nst { | 255 GrPixelConfig surfaceConfig) co nst { |
241 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig ) { | 256 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig ) { |
242 return kBGRA_8888_GrPixelConfig; | 257 return kBGRA_8888_GrPixelConfig; |
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1483 | 1498 |
1484 uint32_t usedAttribArraysMask = 0; | 1499 uint32_t usedAttribArraysMask = 0; |
1485 size_t offset = 0; | 1500 size_t offset = 0; |
1486 | 1501 |
1487 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { | 1502 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { |
1488 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at tribIndex); | 1503 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at tribIndex); |
1489 usedAttribArraysMask |= (1 << attribIndex); | 1504 usedAttribArraysMask |= (1 << attribIndex); |
1490 GrVertexAttribType attribType = attrib.fType; | 1505 GrVertexAttribType attribType = attrib.fType; |
1491 attribState->set(this, | 1506 attribState->set(this, |
1492 attribIndex, | 1507 attribIndex, |
1493 vbuf, | 1508 vbuf->bufferID(), |
1494 GrGLAttribTypeToLayout(attribType).fCount, | 1509 GrGLAttribTypeToLayout(attribType).fCount, |
1495 GrGLAttribTypeToLayout(attribType).fType, | 1510 GrGLAttribTypeToLayout(attribType).fType, |
1496 GrGLAttribTypeToLayout(attribType).fNormalized, | 1511 GrGLAttribTypeToLayout(attribType).fNormalized, |
1497 stride, | 1512 stride, |
1498 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o ffset)); | 1513 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o ffset)); |
1499 offset += attrib.fOffset; | 1514 offset += attrib.fOffset; |
1500 } | 1515 } |
1501 attribState->disableUnusedArrays(this, usedAttribArraysMask); | 1516 attribState->disableUnusedArrays(this, usedAttribArraysMask); |
1502 } | 1517 } |
1503 } | 1518 } |
(...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2611 | 2626 |
2612 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { | 2627 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { |
2613 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2628 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
2614 GR_GL_COLOR_ATTACHMENT0 , | 2629 GR_GL_COLOR_ATTACHMENT0 , |
2615 GR_GL_TEXTURE_2D, | 2630 GR_GL_TEXTURE_2D, |
2616 0, | 2631 0, |
2617 0)); | 2632 0)); |
2618 } | 2633 } |
2619 | 2634 |
2620 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) { | 2635 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) { |
2621 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If neither are | 2636 // If the src is a texture, we can implement the blit as a draw assuming the config is |
2637 // renderable. | |
2638 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals e)) { | |
2639 desc->fOrigin = kDefault_GrSurfaceOrigin; | |
2640 desc->fFlags = kRenderTarget_GrSurfaceFlag; | |
2641 desc->fConfig = src->config(); | |
2642 return true; | |
2643 } | |
2644 | |
2645 // 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- | 2646 // 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 | 2647 // 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. | 2648 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal. |
2625 | 2649 |
2626 // Check for format issues with glCopyTexSubImage2D | 2650 // Check for format issues with glCopyTexSubImage2D |
2627 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna lFormat() && | 2651 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna lFormat() && |
2628 kBGRA_8888_GrPixelConfig == src->config()) { | 2652 kBGRA_8888_GrPixelConfig == src->config()) { |
2629 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit | 2653 // 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. | 2654 // then we set up for that, otherwise fail. |
2631 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { | 2655 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { |
(...skipping 25 matching lines...) Expand all Loading... | |
2657 desc->fConfig = src->config(); | 2681 desc->fConfig = src->config(); |
2658 desc->fOrigin = src->origin(); | 2682 desc->fOrigin = src->origin(); |
2659 desc->fFlags = kNone_GrSurfaceFlags; | 2683 desc->fFlags = kNone_GrSurfaceFlags; |
2660 return true; | 2684 return true; |
2661 } | 2685 } |
2662 | 2686 |
2663 bool GrGLGpu::copySurface(GrSurface* dst, | 2687 bool GrGLGpu::copySurface(GrSurface* dst, |
2664 GrSurface* src, | 2688 GrSurface* src, |
2665 const SkIRect& srcRect, | 2689 const SkIRect& srcRect, |
2666 const SkIPoint& dstPoint) { | 2690 const SkIPoint& dstPoint) { |
2667 bool copied = false; | 2691 if (src->asTexture() && dst->asRenderTarget()) { |
2692 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | |
2693 return true; | |
2694 } | |
2695 | |
2668 if (can_copy_texsubimage(dst, src, this)) { | 2696 if (can_copy_texsubimage(dst, src, this)) { |
2669 GrGLuint srcFBO; | 2697 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
2670 GrGLIRect srcVP; | 2698 return true; |
2671 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem pFBOTarget); | 2699 } |
2672 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 2700 |
2673 SkASSERT(dstTex); | 2701 if (can_blit_framebuffer(dst, src, this)) { |
2674 // We modified the bound FBO | 2702 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
2675 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 2703 } |
2676 GrGLIRect srcGLRect; | 2704 |
2677 srcGLRect.setRelativeTo(srcVP, | 2705 return false; |
2678 srcRect.fLeft, | 2706 } |
2679 srcRect.fTop, | 2707 |
2680 srcRect.width(), | 2708 |
2681 srcRect.height(), | 2709 void GrGLGpu::createCopyProgram() { |
2682 src->origin()); | 2710 SkString vshaderTxt( |
2683 | 2711 "attribute vec2 a_vertex;" |
2684 this->setScratchTextureUnit(); | 2712 "uniform vec4 u_texCoordXform;" |
2685 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | 2713 "uniform vec4 u_posXform;" |
2686 GrGLint dstY; | 2714 "varying vec2 v_texCoord;" |
2687 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | 2715 "void main() {" |
joshualitt
2015/05/13 19:23:17
Add comment to vshader and fshader so we know when
bsalomon
2015/05/15 17:56:31
Done.
| |
2688 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | 2716 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" |
2689 } else { | 2717 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
2690 dstY = dstPoint.fY; | 2718 " gl_Position.zw = vec2(0, 1);" |
2719 "}" | |
2720 ); | |
2721 | |
2722 SkString fshaderTxt( | |
2723 "varying vec2 v_texCoord;" | |
2724 "uniform sampler2D u_texture;" | |
2725 "void main() {" | |
2726 " gl_FragColor = texture2D(u_texture, v_texCoord);" | |
2727 "}" | |
2728 ); | |
2729 | |
2730 const char* fsHeader; | |
2731 const char* vsHeader; | |
2732 if (kGLES_GrGLStandard == this->glStandard()) { | |
2733 vsHeader = "#version 100\n"; | |
2734 fsHeader = "#version 100\nprecision mediump float;\n"; | |
2735 } else { | |
2736 vsHeader = fsHeader = "#version 110\n"; | |
2737 } | |
2738 | |
2739 vshaderTxt.prepend(vsHeader); | |
2740 fshaderTxt.prepend(fsHeader); | |
2741 | |
2742 | |
2743 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); | |
2744 const char* str; | |
2745 GrGLint length; | |
2746 | |
2747 str = vshaderTxt.c_str(); | |
2748 length = SkToInt(vshaderTxt.size()); | |
2749 GrGLuint vshader = GrGLCompileAndAttachShader(fGLContext, fCopyProgram.fProg ram, | |
2750 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); | |
2751 | |
2752 str = fshaderTxt.c_str(); | |
2753 length = SkToInt(fshaderTxt.size()); | |
2754 GrGLuint fshader = GrGLCompileAndAttachShader(fGLContext, fCopyProgram.fProg ram, | |
2755 GR_GL_FRAGMENT_SHADER, &str, & length, 1, &fStats); | |
2756 | |
2757 GL_CALL(LinkProgram(fCopyProgram.fProgram)); | |
2758 | |
2759 GL_CALL_RET(fCopyProgram.fTextureUniform, GetUniformLocation(fCopyProgram.fP rogram, | |
2760 "u_texture")); | |
2761 GL_CALL_RET(fCopyProgram.fPosXformUniform, GetUniformLocation(fCopyProgram.f Program, | |
2762 "u_posXform")) ; | |
2763 GL_CALL_RET(fCopyProgram.fTexCoordXformUniform, GetUniformLocation(fCopyProg ram.fProgram, | |
2764 "u_texCoo rdXform")); | |
2765 | |
2766 GL_CALL(BindAttribLocation(fCopyProgram.fProgram, 0, "a_vertex")); | |
2767 | |
2768 GL_CALL(DeleteShader(vshader)); | |
2769 GL_CALL(DeleteShader(fshader)); | |
2770 | |
2771 GL_CALL(GenBuffers(1, &fCopyProgram.fArrayBuffer)); | |
2772 GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, fCopyProgram.fArrayBuffer)); | |
2773 static const GrGLfloat vdata[] = { | |
2774 0, 0, | |
2775 0, 1, | |
2776 1, 0, | |
2777 1, 1 | |
2778 }; | |
2779 GL_ALLOC_CALL(this->glInterface(), | |
2780 BufferData(GR_GL_ARRAY_BUFFER, | |
2781 (GrGLsizeiptr) sizeof(vdata), | |
2782 vdata, // data ptr | |
2783 GR_GL_STATIC_DRAW)); | |
2784 } | |
2785 | |
2786 void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, | |
2787 GrSurface* src, | |
2788 const SkIRect& srcRect, | |
2789 const SkIPoint& dstPoint) { | |
2790 int w = srcRect.width(); | |
2791 int h = srcRect.height(); | |
2792 | |
2793 GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture()); | |
2794 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_Fil terMode); | |
2795 this->bindTexture(0, params, srcTex); | |
2796 | |
2797 GrGLRenderTarget* dstRT = static_cast<GrGLRenderTarget*>(dst->asRenderTarget ()); | |
2798 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h); | |
2799 this->flushRenderTarget(dstRT, &dstRect); | |
2800 | |
2801 GL_CALL(UseProgram(fCopyProgram.fProgram)); | |
2802 fHWProgramID = fCopyProgram.fProgram; | |
2803 | |
2804 fHWGeometryState.setVertexArrayID(this, 0); | |
2805 | |
2806 auto attribs = fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgram. fArrayBuffer); | |
egdaniel
2015/05/13 19:04:42
I think this is not the best use case for auto sin
bsalomon
2015/05/15 17:56:31
Done.
| |
2807 attribs->set(this, 0, fCopyProgram.fArrayBuffer, 2, GR_GL_FLOAT, false, | |
2808 2 * sizeof(GrGLfloat), 0); | |
2809 | |
2810 | |
2811 // dst rect edges in NDC | |
2812 int dw = dst->width(); | |
2813 int dh = dst->height(); | |
2814 GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f; | |
egdaniel
2015/05/13 19:04:42
little confused at what these equations are doing
bsalomon
2015/05/15 17:56:31
Done.
| |
2815 GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f; | |
2816 GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f; | |
2817 GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f; | |
2818 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | |
2819 dy0 = -dy0; | |
2820 dy1 = -dy1; | |
2821 } | |
2822 | |
2823 // src rect edges in normalized texture space | |
2824 int sw = src->width(); | |
2825 int sh = src->height(); | |
2826 GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft / sw; | |
2827 GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w) / sw; | |
2828 GrGLfloat sy0 = (GrGLfloat)srcRect.fTop / sh; | |
2829 GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h) / sh; | |
2830 if (kBottomLeft_GrSurfaceOrigin == src->origin()) { | |
2831 sy0 = 1.f - sy0; | |
2832 sy1 = 1.f - sy1; | |
2833 } | |
2834 | |
2835 GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0)); | |
2836 GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0, sx0, sy0)); | |
2837 GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0)); | |
2838 | |
2839 GrXferProcessor::BlendInfo blendInfo; | |
2840 blendInfo.reset(); | |
2841 this->flushBlend(blendInfo); | |
2842 this->flushColorWrite(true); | |
2843 this->flushDither(false); | |
2844 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | |
2845 this->flushHWAAState(dstRT, false); | |
2846 this->disableScissor(); | |
2847 GrStencilSettings stencil; | |
2848 stencil.setDisabled(); | |
2849 this->flushStencil(stencil); | |
2850 | |
2851 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); | |
2852 } | |
2853 | |
2854 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, | |
2855 GrSurface* src, | |
2856 const SkIRect& srcRect, | |
2857 const SkIPoint& dstPoint) { | |
2858 SkASSERT(can_copy_texsubimage(dst, src, this)); | |
2859 GrGLuint srcFBO; | |
2860 GrGLIRect srcVP; | |
2861 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBO Target); | |
2862 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | |
2863 SkASSERT(dstTex); | |
2864 // We modified the bound FBO | |
2865 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
2866 GrGLIRect srcGLRect; | |
2867 srcGLRect.setRelativeTo(srcVP, | |
2868 srcRect.fLeft, | |
2869 srcRect.fTop, | |
2870 srcRect.width(), | |
2871 srcRect.height(), | |
2872 src->origin()); | |
2873 | |
2874 this->setScratchTextureUnit(); | |
2875 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | |
2876 GrGLint dstY; | |
2877 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | |
2878 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | |
2879 } else { | |
2880 dstY = dstPoint.fY; | |
2881 } | |
2882 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | |
2883 dstPoint.fX, dstY, | |
2884 srcGLRect.fLeft, srcGLRect.fBottom, | |
2885 srcGLRect.fWidth, srcGLRect.fHeight)); | |
2886 if (srcFBO) { | |
2887 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); | |
2888 } | |
2889 } | |
2890 | |
2891 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, | |
2892 GrSurface* src, | |
2893 const SkIRect& srcRect, | |
2894 const SkIPoint& dstPoint) { | |
2895 SkASSERT(can_blit_framebuffer(dst, src, this)); | |
2896 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | |
2897 srcRect.width(), srcRect.height()); | |
2898 if (dst == src) { | |
2899 if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { | |
2900 return false; | |
2691 } | 2901 } |
2692 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | 2902 } |
2693 dstPoint.fX, dstY, | 2903 |
2694 srcGLRect.fLeft, srcGLRect.fBottom, | 2904 GrGLuint dstFBO; |
2695 srcGLRect.fWidth, srcGLRect.fHeight)); | 2905 GrGLuint srcFBO; |
2696 copied = true; | 2906 GrGLIRect dstVP; |
2697 if (srcFBO) { | 2907 GrGLIRect srcVP; |
2698 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); | 2908 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, |
2699 } | 2909 kDst_TempFBOTarget); |
2700 } else if (can_blit_framebuffer(dst, src, this)) { | 2910 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, |
2701 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | 2911 kSrc_TempFBOTarget); |
2702 srcRect.width(), srcRect.height()); | 2912 // We modified the bound FBO |
2703 bool selfOverlap = false; | 2913 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
2704 if (dst == src) { | 2914 GrGLIRect srcGLRect; |
2705 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); | 2915 GrGLIRect dstGLRect; |
2706 } | 2916 srcGLRect.setRelativeTo(srcVP, |
2707 | 2917 srcRect.fLeft, |
2708 if (!selfOverlap) { | 2918 srcRect.fTop, |
2709 GrGLuint dstFBO; | 2919 srcRect.width(), |
2710 GrGLuint srcFBO; | 2920 srcRect.height(), |
2711 GrGLIRect dstVP; | 2921 src->origin()); |
2712 GrGLIRect srcVP; | 2922 dstGLRect.setRelativeTo(dstVP, |
2713 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, | 2923 dstRect.fLeft, |
2714 kDst_TempFBOTarget); | 2924 dstRect.fTop, |
2715 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, | 2925 dstRect.width(), |
2716 kSrc_TempFBOTarget); | 2926 dstRect.height(), |
2717 // We modified the bound FBO | 2927 dst->origin()); |
2718 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 2928 |
2719 GrGLIRect srcGLRect; | 2929 // BlitFrameBuffer respects the scissor, so disable it. |
2720 GrGLIRect dstGLRect; | 2930 this->disableScissor(); |
2721 srcGLRect.setRelativeTo(srcVP, | 2931 |
2722 srcRect.fLeft, | 2932 GrGLint srcY0; |
2723 srcRect.fTop, | 2933 GrGLint srcY1; |
2724 srcRect.width(), | 2934 // Does the blit need to y-mirror or not? |
2725 srcRect.height(), | 2935 if (src->origin() == dst->origin()) { |
2726 src->origin()); | 2936 srcY0 = srcGLRect.fBottom; |
2727 dstGLRect.setRelativeTo(dstVP, | 2937 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; |
2728 dstRect.fLeft, | 2938 } else { |
2729 dstRect.fTop, | 2939 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; |
2730 dstRect.width(), | 2940 srcY1 = srcGLRect.fBottom; |
2731 dstRect.height(), | 2941 } |
2732 dst->origin()); | 2942 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
2733 | 2943 srcY0, |
2734 // BlitFrameBuffer respects the scissor, so disable it. | 2944 srcGLRect.fLeft + srcGLRect.fWidth, |
2735 this->disableScissor(); | 2945 srcY1, |
2736 | 2946 dstGLRect.fLeft, |
2737 GrGLint srcY0; | 2947 dstGLRect.fBottom, |
2738 GrGLint srcY1; | 2948 dstGLRect.fLeft + dstGLRect.fWidth, |
2739 // Does the blit need to y-mirror or not? | 2949 dstGLRect.fBottom + dstGLRect.fHeight, |
2740 if (src->origin() == dst->origin()) { | 2950 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
2741 srcY0 = srcGLRect.fBottom; | 2951 if (dstFBO) { |
2742 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; | 2952 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); |
2743 } else { | 2953 } |
2744 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; | 2954 if (srcFBO) { |
2745 srcY1 = srcGLRect.fBottom; | 2955 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); |
2746 } | 2956 } |
2747 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | 2957 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 } | 2958 } |
2789 | 2959 |
2790 void GrGLGpu::xferBarrier(GrXferBarrierType type) { | 2960 void GrGLGpu::xferBarrier(GrXferBarrierType type) { |
2791 switch (type) { | 2961 switch (type) { |
2792 case kTexture_GrXferBarrierType: | 2962 case kTexture_GrXferBarrierType: |
2793 SkASSERT(this->caps()->textureBarrierSupport()); | 2963 SkASSERT(this->caps()->textureBarrierSupport()); |
2794 GL_CALL(TextureBarrier()); | 2964 GL_CALL(TextureBarrier()); |
2795 return; | 2965 return; |
2796 case kBlend_GrXferBarrierType: | 2966 case kBlend_GrXferBarrierType: |
2797 SkASSERT(GrDrawTargetCaps::kAdvanced_BlendEquationSupport == | 2967 SkASSERT(GrDrawTargetCaps::kAdvanced_BlendEquationSupport == |
(...skipping 19 matching lines...) Expand all Loading... | |
2817 if (this->caps()->gpuTracingSupport()) { | 2987 if (this->caps()->gpuTracingSupport()) { |
2818 #if GR_FORCE_GPU_TRACE_DEBUGGING | 2988 #if GR_FORCE_GPU_TRACE_DEBUGGING |
2819 SkDebugf("Pop trace marker.\n"); | 2989 SkDebugf("Pop trace marker.\n"); |
2820 #else | 2990 #else |
2821 GL_CALL(PopGroupMarker()); | 2991 GL_CALL(PopGroupMarker()); |
2822 #endif | 2992 #endif |
2823 } | 2993 } |
2824 } | 2994 } |
2825 | 2995 |
2826 /////////////////////////////////////////////////////////////////////////////// | 2996 /////////////////////////////////////////////////////////////////////////////// |
2827 | |
2828 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( | 2997 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( |
2829 GrGLGpu* gpu, | 2998 GrGLGpu* gpu, |
2830 const GrGLVertexBuffer* vbuffer, | 2999 const GrGLVertexBuffer* vbuffer, |
2831 const GrGLIndexBuffer* ibuffer) { | 3000 const GrGLIndexBuffer* ibuffer) { |
2832 SkASSERT(vbuffer); | 3001 SkASSERT(vbuffer); |
3002 GrGLuint vbufferID = vbuffer->bufferID(); | |
3003 GrGLuint* ibufferIDPtr = NULL; | |
3004 GrGLuint ibufferID; | |
3005 if (ibuffer) { | |
3006 ibufferID = ibuffer->bufferID(); | |
3007 ibufferIDPtr = &ibufferID; | |
3008 } | |
3009 return this->internalBind(gpu, vbufferID, ibufferIDPtr); | |
3010 } | |
3011 | |
3012 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBufferToDraw(GrGLGpu * gpu, | |
3013 GrGLuin t vbufferID) { | |
3014 return this->internalBind(gpu, vbufferID, NULL); | |
3015 } | |
3016 | |
3017 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(GrGLGp u* gpu, | |
3018 GrGLui nt vbufferID, | |
3019 GrGLui nt ibufferID) { | |
3020 return this->internalBind(gpu, vbufferID, &ibufferID); | |
3021 } | |
3022 | |
3023 GrGLAttribArrayState* GrGLGpu::HWGeometryState::internalBind(GrGLGpu* gpu, | |
3024 GrGLuint vbufferID, | |
3025 GrGLuint* ibufferID ) { | |
2833 GrGLAttribArrayState* attribState; | 3026 GrGLAttribArrayState* attribState; |
2834 | 3027 |
2835 // We use a vertex array if we're on a core profile and the verts are in a V BO. | 3028 // If one buffer is a client-side array, so must the other. |
2836 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) { | 3029 SkASSERT(!ibufferID || SkToBool(vbufferID) == SkToBool(*ibufferID)); |
3030 if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) { | |
2837 if (!fVBOVertexArray) { | 3031 if (!fVBOVertexArray) { |
2838 GrGLuint arrayID; | 3032 GrGLuint arrayID; |
2839 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); | 3033 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); |
2840 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3034 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2841 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); | 3035 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); |
2842 } | 3036 } |
2843 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, ibuffer); | 3037 if (ibufferID) { |
3038 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID); | |
3039 } else { | |
3040 attribState = fVBOVertexArray->bind(gpu); | |
3041 } | |
2844 } else { | 3042 } else { |
2845 if (ibuffer) { | 3043 if (ibufferID) { |
2846 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID()) ; | 3044 this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID); |
2847 } else { | 3045 } else { |
2848 this->setVertexArrayID(gpu, 0); | 3046 this->setVertexArrayID(gpu, 0); |
2849 } | 3047 } |
2850 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3048 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2851 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3049 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
2852 fDefaultVertexArrayAttribState.resize(attrCount); | 3050 fDefaultVertexArrayAttribState.resize(attrCount); |
2853 } | 3051 } |
2854 attribState = &fDefaultVertexArrayAttribState; | 3052 attribState = &fDefaultVertexArrayAttribState; |
2855 } | 3053 } |
2856 return attribState; | 3054 return attribState; |
2857 } | 3055 } |
OLD | NEW |