Chromium Code Reviews| 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 |