Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(543)

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

Issue 1144433002: Move copy-surface-as-draw fallback to GrGLGpu. (Closed) Base URL: https://skia.googlesource.com/skia.git@vares
Patch Set: more Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLVertexArray.h » ('j') | src/gpu/gl/GrGLVertexArray.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698