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

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

Powered by Google App Engine
This is Rietveld 408576698