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

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

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