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

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

Issue 1161063003: Revert "Revert of Move copy-surface-as-draw fallback to GrGLGpu. (patchset #12 id:220001 of https:/… (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update Created 5 years, 6 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 212
212 fLastSuccessfulStencilFmtIdx = 0; 213 fLastSuccessfulStencilFmtIdx = 0;
213 fHWProgramID = 0; 214 fHWProgramID = 0;
214 fTempSrcFBOID = 0; 215 fTempSrcFBOID = 0;
215 fTempDstFBOID = 0; 216 fTempDstFBOID = 0;
216 fStencilClearFBOID = 0; 217 fStencilClearFBOID = 0;
217 218
218 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 219 if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
219 fPathRendering.reset(new GrGLPathRendering(this)); 220 fPathRendering.reset(new GrGLPathRendering(this));
220 } 221 }
222
223 this->createCopyProgram();
221 } 224 }
222 225
223 GrGLGpu::~GrGLGpu() { 226 GrGLGpu::~GrGLGpu() {
224 if (0 != fHWProgramID) { 227 if (0 != fHWProgramID) {
225 // detach the current program so there is no confusion on OpenGL's part 228 // detach the current program so there is no confusion on OpenGL's part
226 // that we want it to be deleted 229 // that we want it to be deleted
227 SkASSERT(fHWProgramID == fCurrentProgram->programID());
228 GL_CALL(UseProgram(0)); 230 GL_CALL(UseProgram(0));
229 } 231 }
230 232
231 if (0 != fTempSrcFBOID) { 233 if (0 != fTempSrcFBOID) {
232 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); 234 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
233 } 235 }
234 if (0 != fTempDstFBOID) { 236 if (0 != fTempDstFBOID) {
235 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); 237 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
236 } 238 }
237 if (0 != fStencilClearFBOID) { 239 if (0 != fStencilClearFBOID) {
238 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); 240 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
239 } 241 }
240 242
243 if (0 != fCopyProgram.fArrayBuffer) {
244 GL_CALL(DeleteBuffers(1, &fCopyProgram.fArrayBuffer));
245 }
246
247 if (0 != fCopyProgram.fProgram) {
248 GL_CALL(DeleteProgram(fCopyProgram.fProgram));
249 }
250
241 delete fProgramCache; 251 delete fProgramCache;
242 } 252 }
243 253
244 void GrGLGpu::contextAbandoned() { 254 void GrGLGpu::contextAbandoned() {
245 INHERITED::contextAbandoned(); 255 INHERITED::contextAbandoned();
246 fProgramCache->abandon(); 256 fProgramCache->abandon();
247 fHWProgramID = 0; 257 fHWProgramID = 0;
248 fTempSrcFBOID = 0; 258 fTempSrcFBOID = 0;
249 fTempDstFBOID = 0; 259 fTempDstFBOID = 0;
250 fStencilClearFBOID = 0; 260 fStencilClearFBOID = 0;
261 fCopyProgram.fArrayBuffer = 0;
262 fCopyProgram.fProgram = 0;
251 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 263 if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
252 this->glPathRendering()->abandonGpuResources(); 264 this->glPathRendering()->abandonGpuResources();
253 } 265 }
254 } 266 }
255 267
256 /////////////////////////////////////////////////////////////////////////////// 268 ///////////////////////////////////////////////////////////////////////////////
257 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, 269 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig,
258 GrPixelConfig surfaceConfig) co nst { 270 GrPixelConfig surfaceConfig) co nst {
259 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig ) { 271 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig ) {
260 return kBGRA_8888_GrPixelConfig; 272 return kBGRA_8888_GrPixelConfig;
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 1440
1429 bool GrGLGpu::flushGLState(const DrawArgs& args) { 1441 bool GrGLGpu::flushGLState(const DrawArgs& args) {
1430 GrXferProcessor::BlendInfo blendInfo; 1442 GrXferProcessor::BlendInfo blendInfo;
1431 const GrPipeline& pipeline = *args.fPipeline; 1443 const GrPipeline& pipeline = *args.fPipeline;
1432 args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo); 1444 args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo);
1433 1445
1434 this->flushDither(pipeline.isDitherState()); 1446 this->flushDither(pipeline.isDitherState());
1435 this->flushColorWrite(blendInfo.fWriteColor); 1447 this->flushColorWrite(blendInfo.fWriteColor);
1436 this->flushDrawFace(pipeline.getDrawFace()); 1448 this->flushDrawFace(pipeline.getDrawFace());
1437 1449
1438 fCurrentProgram.reset(fProgramCache->getProgram(args)); 1450 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(args));
1439 if (NULL == fCurrentProgram.get()) { 1451 if (!program) {
1440 GrCapsDebugf(this->caps(), "Failed to create program!\n"); 1452 GrCapsDebugf(this->caps(), "Failed to create program!\n");
1441 return false; 1453 return false;
1442 } 1454 }
1443 1455
1444 fCurrentProgram.get()->ref(); 1456 GrGLuint programID = program->programID();
1445
1446 GrGLuint programID = fCurrentProgram->programID();
1447 if (fHWProgramID != programID) { 1457 if (fHWProgramID != programID) {
1448 GL_CALL(UseProgram(programID)); 1458 GL_CALL(UseProgram(programID));
1449 fHWProgramID = programID; 1459 fHWProgramID = programID;
1450 } 1460 }
1451 1461
1452 if (blendInfo.fWriteColor) { 1462 if (blendInfo.fWriteColor) {
1453 this->flushBlend(blendInfo); 1463 this->flushBlend(blendInfo);
1454 } 1464 }
1455 1465
1456 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr acker); 1466 program->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker);
1457 1467
1458 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa rget()); 1468 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa rget());
1459 this->flushStencil(pipeline.getStencil()); 1469 this->flushStencil(pipeline.getStencil());
1460 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or igin()); 1470 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or igin());
1461 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); 1471 this->flushHWAAState(glRT, pipeline.isHWAntialiasState());
1462 1472
1463 // This must come after textures are flushed because a texture may need 1473 // This must come after textures are flushed because a texture may need
1464 // to be msaa-resolved (which will modify bound FBO state). 1474 // to be msaa-resolved (which will modify bound FBO state).
1465 this->flushRenderTarget(glRT, NULL); 1475 this->flushRenderTarget(glRT, NULL);
1466 1476
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 1511
1502 uint32_t usedAttribArraysMask = 0; 1512 uint32_t usedAttribArraysMask = 0;
1503 size_t offset = 0; 1513 size_t offset = 0;
1504 1514
1505 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { 1515 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) {
1506 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at tribIndex); 1516 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at tribIndex);
1507 usedAttribArraysMask |= (1 << attribIndex); 1517 usedAttribArraysMask |= (1 << attribIndex);
1508 GrVertexAttribType attribType = attrib.fType; 1518 GrVertexAttribType attribType = attrib.fType;
1509 attribState->set(this, 1519 attribState->set(this,
1510 attribIndex, 1520 attribIndex,
1511 vbuf, 1521 vbuf->bufferID(),
1512 GrGLAttribTypeToLayout(attribType).fCount, 1522 GrGLAttribTypeToLayout(attribType).fCount,
1513 GrGLAttribTypeToLayout(attribType).fType, 1523 GrGLAttribTypeToLayout(attribType).fType,
1514 GrGLAttribTypeToLayout(attribType).fNormalized, 1524 GrGLAttribTypeToLayout(attribType).fNormalized,
1515 stride, 1525 stride,
1516 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o ffset)); 1526 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o ffset));
1517 offset += attrib.fOffset; 1527 offset += attrib.fOffset;
1518 } 1528 }
1519 attribState->disableUnusedArrays(this, usedAttribArraysMask); 1529 attribState->disableUnusedArrays(this, usedAttribArraysMask);
1520 } 1530 }
1521 } 1531 }
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 2619
2610 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { 2620 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) {
2611 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 2621 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
2612 GR_GL_COLOR_ATTACHMENT0 , 2622 GR_GL_COLOR_ATTACHMENT0 ,
2613 GR_GL_TEXTURE_2D, 2623 GR_GL_TEXTURE_2D,
2614 0, 2624 0,
2615 0)); 2625 0));
2616 } 2626 }
2617 2627
2618 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) { 2628 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
2619 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If neither are 2629 // If the src is a texture, we can implement the blit as a draw assuming the config is
2630 // renderable.
2631 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals e)) {
2632 desc->fOrigin = kDefault_GrSurfaceOrigin;
2633 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2634 desc->fConfig = src->config();
2635 return true;
2636 }
2637
2638 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2620 // possible and we return false to fallback to creating a render target dst for render-to- 2639 // possible and we return false to fallback to creating a render target dst for render-to-
2621 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger ing temporary fbo 2640 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger ing temporary fbo
2622 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal. 2641 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
2623 2642
2624 // Check for format issues with glCopyTexSubImage2D 2643 // Check for format issues with glCopyTexSubImage2D
2625 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna lFormat() && 2644 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna lFormat() &&
2626 kBGRA_8888_GrPixelConfig == src->config()) { 2645 kBGRA_8888_GrPixelConfig == src->config()) {
2627 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit 2646 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2628 // then we set up for that, otherwise fail. 2647 // then we set up for that, otherwise fail.
2629 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { 2648 if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) {
(...skipping 25 matching lines...) Expand all
2655 desc->fConfig = src->config(); 2674 desc->fConfig = src->config();
2656 desc->fOrigin = src->origin(); 2675 desc->fOrigin = src->origin();
2657 desc->fFlags = kNone_GrSurfaceFlags; 2676 desc->fFlags = kNone_GrSurfaceFlags;
2658 return true; 2677 return true;
2659 } 2678 }
2660 2679
2661 bool GrGLGpu::copySurface(GrSurface* dst, 2680 bool GrGLGpu::copySurface(GrSurface* dst,
2662 GrSurface* src, 2681 GrSurface* src,
2663 const SkIRect& srcRect, 2682 const SkIRect& srcRect,
2664 const SkIPoint& dstPoint) { 2683 const SkIPoint& dstPoint) {
2665 bool copied = false; 2684 if (src->asTexture() && dst->asRenderTarget()) {
2685 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
2686 return true;
2687 }
2688
2666 if (can_copy_texsubimage(dst, src, this)) { 2689 if (can_copy_texsubimage(dst, src, this)) {
2667 GrGLuint srcFBO; 2690 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
2668 GrGLIRect srcVP; 2691 return true;
2669 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem pFBOTarget); 2692 }
2670 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); 2693
2671 SkASSERT(dstTex); 2694 if (can_blit_framebuffer(dst, src, this)) {
2672 // We modified the bound FBO 2695 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
2673 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; 2696 }
2674 GrGLIRect srcGLRect; 2697
2675 srcGLRect.setRelativeTo(srcVP, 2698 return false;
2676 srcRect.fLeft, 2699 }
2677 srcRect.fTop, 2700
2678 srcRect.width(), 2701
2679 srcRect.height(), 2702 void GrGLGpu::createCopyProgram() {
2680 src->origin()); 2703 const char* version = GrGetGLSLVersionDecl(this->ctxInfo());
2681 2704
2682 this->setScratchTextureUnit(); 2705 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier);
2683 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); 2706 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
2684 GrGLint dstY; 2707 GrShaderVar::kUniform_TypeModifier);
2685 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 2708 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier);
2686 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); 2709 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier);
2687 } else { 2710 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier);
2688 dstY = dstPoint.fY; 2711 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier);
2712
2713 SkString vshaderTxt(version);
2714 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt);
2715 vshaderTxt.append(";");
2716 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt);
2717 vshaderTxt.append(";");
2718 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt);
2719 vshaderTxt.append(";");
2720 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt);
2721 vshaderTxt.append(";");
2722
2723 vshaderTxt.append(
2724 "// Copy Program VS\n"
2725 "void main() {"
2726 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
2727 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
2728 " gl_Position.zw = vec2(0, 1);"
2729 "}"
2730 );
2731
2732 SkString fshaderTxt(version);
2733 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, this->g lStandard(),
2734 &fshaderTxt);
2735 vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
2736 vTexCoord.appendDecl(this->ctxInfo(), &fshaderTxt);
2737 fshaderTxt.append(";");
2738 uTexture.appendDecl(this->ctxInfo(), &fshaderTxt);
2739 fshaderTxt.append(";");
2740 const char* fsOutName;
2741 if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) {
2742 oFragColor.appendDecl(this->ctxInfo(), &fshaderTxt);
2743 fshaderTxt.append(";");
2744 fsOutName = oFragColor.c_str();
2745 } else {
2746 fsOutName = "gl_FragColor";
2747 }
2748 fshaderTxt.appendf(
2749 "// Copy Program FS\n"
2750 "void main() {"
2751 " %s = %s(u_texture, v_texCoord);"
2752 "}",
2753 fsOutName,
2754 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
2755 );
2756
2757 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram());
2758 const char* str;
2759 GrGLint length;
2760
2761 str = vshaderTxt.c_str();
2762 length = SkToInt(vshaderTxt.size());
2763 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram,
2764 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats);
2765
2766 str = fshaderTxt.c_str();
2767 length = SkToInt(fshaderTxt.size());
2768 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram,
2769 GR_GL_FRAGMENT_SHADER, &str, & length, 1, &fStats);
2770
2771 GL_CALL(LinkProgram(fCopyProgram.fProgram));
2772
2773 GL_CALL_RET(fCopyProgram.fTextureUniform, GetUniformLocation(fCopyProgram.fP rogram,
2774 "u_texture"));
2775 GL_CALL_RET(fCopyProgram.fPosXformUniform, GetUniformLocation(fCopyProgram.f Program,
2776 "u_posXform")) ;
2777 GL_CALL_RET(fCopyProgram.fTexCoordXformUniform, GetUniformLocation(fCopyProg ram.fProgram,
2778 "u_texCoo rdXform"));
2779
2780 GL_CALL(BindAttribLocation(fCopyProgram.fProgram, 0, "a_vertex"));
2781
2782 GL_CALL(DeleteShader(vshader));
2783 GL_CALL(DeleteShader(fshader));
2784
2785 GL_CALL(GenBuffers(1, &fCopyProgram.fArrayBuffer));
2786 fHWGeometryState.setVertexBufferID(this, fCopyProgram.fArrayBuffer);
2787 static const GrGLfloat vdata[] = {
2788 0, 0,
2789 0, 1,
2790 1, 0,
2791 1, 1
2792 };
2793 GL_ALLOC_CALL(this->glInterface(),
2794 BufferData(GR_GL_ARRAY_BUFFER,
2795 (GrGLsizeiptr) sizeof(vdata),
2796 vdata, // data ptr
2797 GR_GL_STATIC_DRAW));
2798 }
2799
2800 void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
2801 GrSurface* src,
2802 const SkIRect& srcRect,
2803 const SkIPoint& dstPoint) {
2804 int w = srcRect.width();
2805 int h = srcRect.height();
2806
2807 GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
2808 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_Fil terMode);
2809 this->bindTexture(0, params, srcTex);
2810
2811 GrGLRenderTarget* dstRT = static_cast<GrGLRenderTarget*>(dst->asRenderTarget ());
2812 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
2813 this->flushRenderTarget(dstRT, &dstRect);
2814
2815 GL_CALL(UseProgram(fCopyProgram.fProgram));
2816 fHWProgramID = fCopyProgram.fProgram;
2817
2818 fHWGeometryState.setVertexArrayID(this, 0);
2819
2820 GrGLAttribArrayState* attribs =
2821 fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgram.fArrayBuffe r);
2822 attribs->set(this, 0, fCopyProgram.fArrayBuffer, 2, GR_GL_FLOAT, false,
2823 2 * sizeof(GrGLfloat), 0);
2824
2825
2826 // dst rect edges in NDC (-1 to 1)
2827 int dw = dst->width();
2828 int dh = dst->height();
2829 GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
2830 GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
2831 GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
2832 GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
2833 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
2834 dy0 = -dy0;
2835 dy1 = -dy1;
2836 }
2837
2838 // src rect edges in normalized texture space (0 to 1)
2839 int sw = src->width();
2840 int sh = src->height();
2841 GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft / sw;
2842 GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w) / sw;
2843 GrGLfloat sy0 = (GrGLfloat)srcRect.fTop / sh;
2844 GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h) / sh;
2845 if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
2846 sy0 = 1.f - sy0;
2847 sy1 = 1.f - sy1;
2848 }
2849
2850 GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
2851 GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0, sx0, sy0));
2852 GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0));
2853
2854 GrXferProcessor::BlendInfo blendInfo;
2855 blendInfo.reset();
2856 this->flushBlend(blendInfo);
2857 this->flushColorWrite(true);
2858 this->flushDither(false);
2859 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
2860 this->flushHWAAState(dstRT, false);
2861 this->disableScissor();
2862 GrStencilSettings stencil;
2863 stencil.setDisabled();
2864 this->flushStencil(stencil);
2865
2866 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
2867 }
2868
2869 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
2870 GrSurface* src,
2871 const SkIRect& srcRect,
2872 const SkIPoint& dstPoint) {
2873 SkASSERT(can_copy_texsubimage(dst, src, this));
2874 GrGLuint srcFBO;
2875 GrGLIRect srcVP;
2876 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBO Target);
2877 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
2878 SkASSERT(dstTex);
2879 // We modified the bound FBO
2880 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
2881 GrGLIRect srcGLRect;
2882 srcGLRect.setRelativeTo(srcVP,
2883 srcRect.fLeft,
2884 srcRect.fTop,
2885 srcRect.width(),
2886 srcRect.height(),
2887 src->origin());
2888
2889 this->setScratchTextureUnit();
2890 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID()));
2891 GrGLint dstY;
2892 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
2893 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
2894 } else {
2895 dstY = dstPoint.fY;
2896 }
2897 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0,
2898 dstPoint.fX, dstY,
2899 srcGLRect.fLeft, srcGLRect.fBottom,
2900 srcGLRect.fWidth, srcGLRect.fHeight));
2901 if (srcFBO) {
2902 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER);
2903 }
2904 }
2905
2906 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
2907 GrSurface* src,
2908 const SkIRect& srcRect,
2909 const SkIPoint& dstPoint) {
2910 SkASSERT(can_blit_framebuffer(dst, src, this));
2911 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
2912 srcRect.width(), srcRect.height());
2913 if (dst == src) {
2914 if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
2915 return false;
2689 } 2916 }
2690 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, 2917 }
2691 dstPoint.fX, dstY, 2918
2692 srcGLRect.fLeft, srcGLRect.fBottom, 2919 GrGLuint dstFBO;
2693 srcGLRect.fWidth, srcGLRect.fHeight)); 2920 GrGLuint srcFBO;
2694 copied = true; 2921 GrGLIRect dstVP;
2695 if (srcFBO) { 2922 GrGLIRect srcVP;
2696 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); 2923 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP,
2697 } 2924 kDst_TempFBOTarget);
2698 } else if (can_blit_framebuffer(dst, src, this)) { 2925 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP,
2699 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, 2926 kSrc_TempFBOTarget);
2700 srcRect.width(), srcRect.height()); 2927 // We modified the bound FBO
2701 bool selfOverlap = false; 2928 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
2702 if (dst == src) { 2929 GrGLIRect srcGLRect;
2703 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); 2930 GrGLIRect dstGLRect;
2704 } 2931 srcGLRect.setRelativeTo(srcVP,
2705 2932 srcRect.fLeft,
2706 if (!selfOverlap) { 2933 srcRect.fTop,
2707 GrGLuint dstFBO; 2934 srcRect.width(),
2708 GrGLuint srcFBO; 2935 srcRect.height(),
2709 GrGLIRect dstVP; 2936 src->origin());
2710 GrGLIRect srcVP; 2937 dstGLRect.setRelativeTo(dstVP,
2711 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, 2938 dstRect.fLeft,
2712 kDst_TempFBOTarget); 2939 dstRect.fTop,
2713 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, 2940 dstRect.width(),
2714 kSrc_TempFBOTarget); 2941 dstRect.height(),
2715 // We modified the bound FBO 2942 dst->origin());
2716 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; 2943
2717 GrGLIRect srcGLRect; 2944 // BlitFrameBuffer respects the scissor, so disable it.
2718 GrGLIRect dstGLRect; 2945 this->disableScissor();
2719 srcGLRect.setRelativeTo(srcVP, 2946
2720 srcRect.fLeft, 2947 GrGLint srcY0;
2721 srcRect.fTop, 2948 GrGLint srcY1;
2722 srcRect.width(), 2949 // Does the blit need to y-mirror or not?
2723 srcRect.height(), 2950 if (src->origin() == dst->origin()) {
2724 src->origin()); 2951 srcY0 = srcGLRect.fBottom;
2725 dstGLRect.setRelativeTo(dstVP, 2952 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
2726 dstRect.fLeft, 2953 } else {
2727 dstRect.fTop, 2954 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
2728 dstRect.width(), 2955 srcY1 = srcGLRect.fBottom;
2729 dstRect.height(), 2956 }
2730 dst->origin()); 2957 GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
2731 2958 srcY0,
2732 // BlitFrameBuffer respects the scissor, so disable it. 2959 srcGLRect.fLeft + srcGLRect.fWidth,
2733 this->disableScissor(); 2960 srcY1,
2734 2961 dstGLRect.fLeft,
2735 GrGLint srcY0; 2962 dstGLRect.fBottom,
2736 GrGLint srcY1; 2963 dstGLRect.fLeft + dstGLRect.fWidth,
2737 // Does the blit need to y-mirror or not? 2964 dstGLRect.fBottom + dstGLRect.fHeight,
2738 if (src->origin() == dst->origin()) { 2965 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
2739 srcY0 = srcGLRect.fBottom; 2966 if (dstFBO) {
2740 srcY1 = srcGLRect.fBottom + srcGLRect.fHeight; 2967 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER);
2741 } else { 2968 }
2742 srcY0 = srcGLRect.fBottom + srcGLRect.fHeight; 2969 if (srcFBO) {
2743 srcY1 = srcGLRect.fBottom; 2970 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER);
2744 } 2971 }
2745 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, 2972 return true;
2746 srcY0,
2747 srcGLRect.fLeft + srcGLRect.fWidth,
2748 srcY1,
2749 dstGLRect.fLeft,
2750 dstGLRect.fBottom,
2751 dstGLRect.fLeft + dstGLRect.fWidth,
2752 dstGLRect.fBottom + dstGLRect.fHeight,
2753 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
2754 if (dstFBO) {
2755 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER);
2756 }
2757 if (srcFBO) {
2758 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER);
2759 }
2760 copied = true;
2761 }
2762 }
2763 return copied;
2764 }
2765
2766 bool GrGLGpu::canCopySurface(const GrSurface* dst,
2767 const GrSurface* src,
2768 const SkIRect& srcRect,
2769 const SkIPoint& dstPoint) {
2770 // This mirrors the logic in onCopySurface.
2771 if (can_copy_texsubimage(dst, src, this)) {
2772 return true;
2773 }
2774 if (can_blit_framebuffer(dst, src, this)) {
2775 if (dst == src) {
2776 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
2777 srcRect.width(), srcRect.height( ));
2778 if(!SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
2779 return true;
2780 }
2781 } else {
2782 return true;
2783 }
2784 }
2785 return false;
2786 } 2973 }
2787 2974
2788 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { 2975 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
2789 switch (type) { 2976 switch (type) {
2790 case kTexture_GrXferBarrierType: { 2977 case kTexture_GrXferBarrierType: {
2791 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); 2978 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt);
2792 if (glrt->textureFBOID() != glrt->renderFBOID()) { 2979 if (glrt->textureFBOID() != glrt->renderFBOID()) {
2793 // The render target uses separate storage so no need for glText ureBarrier. 2980 // The render target uses separate storage so no need for glText ureBarrier.
2794 // FIXME: The render target will resolve automatically when its texture is bound, 2981 // FIXME: The render target will resolve automatically when its texture is bound,
2795 // but we could resolve only the bounds that will be read if we do it here instead. 2982 // but we could resolve only the bounds that will be read if we do it here instead.
(...skipping 27 matching lines...) Expand all
2823 if (this->caps()->gpuTracingSupport()) { 3010 if (this->caps()->gpuTracingSupport()) {
2824 #if GR_FORCE_GPU_TRACE_DEBUGGING 3011 #if GR_FORCE_GPU_TRACE_DEBUGGING
2825 SkDebugf("Pop trace marker.\n"); 3012 SkDebugf("Pop trace marker.\n");
2826 #else 3013 #else
2827 GL_CALL(PopGroupMarker()); 3014 GL_CALL(PopGroupMarker());
2828 #endif 3015 #endif
2829 } 3016 }
2830 } 3017 }
2831 3018
2832 /////////////////////////////////////////////////////////////////////////////// 3019 ///////////////////////////////////////////////////////////////////////////////
2833
2834 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw( 3020 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(
2835 GrGLGpu* gpu, 3021 GrGLGpu* gpu,
2836 const GrGLVertexBuffer* vbuffer, 3022 const GrGLVertexBuffer* vbuffer,
2837 const GrGLIndexBuffer* ibuffer) { 3023 const GrGLIndexBuffer* ibuffer) {
2838 SkASSERT(vbuffer); 3024 SkASSERT(vbuffer);
3025 GrGLuint vbufferID = vbuffer->bufferID();
3026 GrGLuint* ibufferIDPtr = NULL;
3027 GrGLuint ibufferID;
3028 if (ibuffer) {
3029 ibufferID = ibuffer->bufferID();
3030 ibufferIDPtr = &ibufferID;
3031 }
3032 return this->internalBind(gpu, vbufferID, ibufferIDPtr);
3033 }
3034
3035 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBufferToDraw(GrGLGpu * gpu,
3036 GrGLuin t vbufferID) {
3037 return this->internalBind(gpu, vbufferID, NULL);
3038 }
3039
3040 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(GrGLGp u* gpu,
3041 GrGLui nt vbufferID,
3042 GrGLui nt ibufferID) {
3043 return this->internalBind(gpu, vbufferID, &ibufferID);
3044 }
3045
3046 GrGLAttribArrayState* GrGLGpu::HWGeometryState::internalBind(GrGLGpu* gpu,
3047 GrGLuint vbufferID,
3048 GrGLuint* ibufferID ) {
2839 GrGLAttribArrayState* attribState; 3049 GrGLAttribArrayState* attribState;
2840 3050
2841 // We use a vertex array if we're on a core profile and the verts are in a V BO. 3051 if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) {
2842 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) {
2843 if (!fVBOVertexArray) { 3052 if (!fVBOVertexArray) {
2844 GrGLuint arrayID; 3053 GrGLuint arrayID;
2845 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); 3054 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
2846 int attrCount = gpu->glCaps().maxVertexAttributes(); 3055 int attrCount = gpu->glCaps().maxVertexAttributes();
2847 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount)); 3056 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount));
2848 } 3057 }
2849 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, ibuffer); 3058 if (ibufferID) {
3059 attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID);
3060 } else {
3061 attribState = fVBOVertexArray->bind(gpu);
3062 }
2850 } else { 3063 } else {
2851 if (ibuffer) { 3064 if (ibufferID) {
2852 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID()) ; 3065 this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID);
2853 } else { 3066 } else {
2854 this->setVertexArrayID(gpu, 0); 3067 this->setVertexArrayID(gpu, 0);
2855 } 3068 }
2856 int attrCount = gpu->glCaps().maxVertexAttributes(); 3069 int attrCount = gpu->glCaps().maxVertexAttributes();
2857 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3070 if (fDefaultVertexArrayAttribState.count() != attrCount) {
2858 fDefaultVertexArrayAttribState.resize(attrCount); 3071 fDefaultVertexArrayAttribState.resize(attrCount);
2859 } 3072 }
2860 attribState = &fDefaultVertexArrayAttribState; 3073 attribState = &fDefaultVertexArrayAttribState;
2861 } 3074 }
2862 return attribState; 3075 return attribState;
2863 } 3076 }
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