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

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

Issue 1451683002: Initial version of external_oes texture support and unit test (Closed) Base URL: https://skia.googlesource.com/skia.git@target
Patch Set: again Created 5 years, 1 month 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/GrGLInterface.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 "GrGLGLSL.h" 10 #include "GrGLGLSL.h"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 226 }
227 fHWProgramID = 0; 227 fHWProgramID = 0;
228 fTempSrcFBOID = 0; 228 fTempSrcFBOID = 0;
229 fTempDstFBOID = 0; 229 fTempDstFBOID = 0;
230 fStencilClearFBOID = 0; 230 fStencilClearFBOID = 0;
231 231
232 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 232 if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
233 fPathRendering.reset(new GrGLPathRendering(this)); 233 fPathRendering.reset(new GrGLPathRendering(this));
234 } 234 }
235 235
236 this->createCopyProgram(); 236 this->createCopyPrograms();
237 } 237 }
238 238
239 GrGLGpu::~GrGLGpu() { 239 GrGLGpu::~GrGLGpu() {
240 if (0 != fHWProgramID) { 240 if (0 != fHWProgramID) {
241 // detach the current program so there is no confusion on OpenGL's part 241 // detach the current program so there is no confusion on OpenGL's part
242 // that we want it to be deleted 242 // that we want it to be deleted
243 GL_CALL(UseProgram(0)); 243 GL_CALL(UseProgram(0));
244 } 244 }
245 245
246 if (0 != fTempSrcFBOID) { 246 if (0 != fTempSrcFBOID) {
247 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); 247 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
248 } 248 }
249 if (0 != fTempDstFBOID) { 249 if (0 != fTempDstFBOID) {
250 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); 250 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
251 } 251 }
252 if (0 != fStencilClearFBOID) { 252 if (0 != fStencilClearFBOID) {
253 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); 253 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
254 } 254 }
255 255
256 if (0 != fCopyProgram.fArrayBuffer) { 256 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
257 GL_CALL(DeleteBuffers(1, &fCopyProgram.fArrayBuffer)); 257 if (0 != fCopyPrograms[i].fProgram) {
258 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
259 }
258 } 260 }
259 261 if (0 != fCopyProgramArrayBuffer) {
260 if (0 != fCopyProgram.fProgram) { 262 GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer));
261 GL_CALL(DeleteProgram(fCopyProgram.fProgram));
262 } 263 }
263 264
264 delete fProgramCache; 265 delete fProgramCache;
265 } 266 }
266 267
267 void GrGLGpu::contextAbandoned() { 268 void GrGLGpu::contextAbandoned() {
268 INHERITED::contextAbandoned(); 269 INHERITED::contextAbandoned();
269 fProgramCache->abandon(); 270 fProgramCache->abandon();
270 fHWProgramID = 0; 271 fHWProgramID = 0;
271 fTempSrcFBOID = 0; 272 fTempSrcFBOID = 0;
272 fTempDstFBOID = 0; 273 fTempDstFBOID = 0;
273 fStencilClearFBOID = 0; 274 fStencilClearFBOID = 0;
274 fCopyProgram.fArrayBuffer = 0; 275 fCopyProgramArrayBuffer = 0;
275 fCopyProgram.fProgram = 0; 276 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
277 fCopyPrograms[i].fProgram = 0;
278 }
276 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 279 if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
277 this->glPathRendering()->abandonGpuResources(); 280 this->glPathRendering()->abandonGpuResources();
278 } 281 }
279 } 282 }
280 283
281 /////////////////////////////////////////////////////////////////////////////// 284 ///////////////////////////////////////////////////////////////////////////////
282 285
283 void GrGLGpu::onResetContext(uint32_t resetBits) { 286 void GrGLGpu::onResetContext(uint32_t resetBits) {
284 // we don't use the zb at all 287 // we don't use the zb at all
285 if (resetBits & kMisc_GrGLBackendState) { 288 if (resetBits & kMisc_GrGLBackendState) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (!info || !info->fID) { 425 if (!info || !info->fID) {
423 return nullptr; 426 return nullptr;
424 } 427 }
425 #endif 428 #endif
426 429
427 int maxSize = this->caps()->maxTextureSize(); 430 int maxSize = this->caps()->maxTextureSize();
428 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 431 if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
429 return nullptr; 432 return nullptr;
430 } 433 }
431 434
435 // next line relies on GrBackendTextureDesc's flags matching GrTexture's
436 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g);
437
432 GrGLTexture::IDDesc idDesc; 438 GrGLTexture::IDDesc idDesc;
433 GrSurfaceDesc surfDesc; 439 GrSurfaceDesc surfDesc;
434 440
435 #ifdef SK_IGNORE_GL_TEXTURE_TARGET 441 #ifdef SK_IGNORE_GL_TEXTURE_TARGET
436 idDesc.fInfo.fID = static_cast<GrGLuint>(desc.fTextureHandle); 442 idDesc.fInfo.fID = static_cast<GrGLuint>(desc.fTextureHandle);
437 // We only support GL_TEXTURE_2D at the moment. 443 // We only support GL_TEXTURE_2D at the moment.
438 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; 444 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D;
439 #else 445 #else
440 idDesc.fInfo = *info; 446 idDesc.fInfo = *info;
441 #endif 447 #endif
448 if (GR_GL_TEXTURE_EXTERNAL == idDesc.fInfo.fTarget) {
449 if (renderTarget) {
450 // This combination is not supported.
451 return nullptr;
452 }
453 if (!this->glCaps().externalTextureSupport()) {
454 return nullptr;
455 }
456 }
442 457
443 switch (ownership) { 458 switch (ownership) {
444 case kAdopt_GrWrapOwnership: 459 case kAdopt_GrWrapOwnership:
445 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 460 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
446 break; 461 break;
447 case kBorrow_GrWrapOwnership: 462 case kBorrow_GrWrapOwnership:
448 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 463 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
449 break; 464 break;
450 } 465 }
451 466
452 // next line relies on GrBackendTextureDesc's flags matching GrTexture's
453 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; 467 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
454 surfDesc.fWidth = desc.fWidth; 468 surfDesc.fWidth = desc.fWidth;
455 surfDesc.fHeight = desc.fHeight; 469 surfDesc.fHeight = desc.fHeight;
456 surfDesc.fConfig = desc.fConfig; 470 surfDesc.fConfig = desc.fConfig;
457 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); 471 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() );
458 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g);
459 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly 472 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly
460 // assuming the old behaviour, which is that backend textures are always 473 // assuming the old behaviour, which is that backend textures are always
461 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: 474 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to:
462 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); 475 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
463 if (kDefault_GrSurfaceOrigin == desc.fOrigin) { 476 if (kDefault_GrSurfaceOrigin == desc.fOrigin) {
464 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; 477 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
465 } else { 478 } else {
466 surfDesc.fOrigin = desc.fOrigin; 479 surfDesc.fOrigin = desc.fOrigin;
467 } 480 }
468 481
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 DrawPreference* drawPreference, 530 DrawPreference* drawPreference,
518 WritePixelTempDrawInfo* tempDrawInfo) { 531 WritePixelTempDrawInfo* tempDrawInfo) {
519 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { 532 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) {
520 return false; 533 return false;
521 } 534 }
522 535
523 // This subclass only allows writes to textures. If the dst is not a texture we have to draw 536 // This subclass only allows writes to textures. If the dst is not a texture we have to draw
524 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. 537 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y.
525 if (!dstSurface->asTexture()) { 538 if (!dstSurface->asTexture()) {
526 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 539 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
540 } else {
541 GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture() );
542 if (GR_GL_TEXTURE_2D != texture->target()) {
543 // We don't currently support writing pixels to non-TEXTURE_2D text ures.
544 return false;
545 }
527 } 546 }
528 547
529 if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConf ig)) { 548 if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConf ig)) {
530 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 549 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
531 } 550 }
532 551
533 tempDrawInfo->fSwapRAndB = false; 552 tempDrawInfo->fSwapRAndB = false;
534 553
535 // These settings we will always want if a temp draw is performed. Initially set the config 554 // These settings we will always want if a temp draw is performed. Initially set the config
536 // to srcConfig, though that may be modified if we decide to do a R/G swap. 555 // to srcConfig, though that may be modified if we decide to do a R/G swap.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 597 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
579 if (!glTex) { 598 if (!glTex) {
580 return false; 599 return false;
581 } 600 }
582 601
583 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels. 602 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels.
584 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 603 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
585 return false; 604 return false;
586 } 605 }
587 606
607 // Write pixels is only implemented for TEXTURE_2D textures
608 if (GR_GL_TEXTURE_2D != glTex->target()) {
609 return false;
610 }
611
588 this->setScratchTextureUnit(); 612 this->setScratchTextureUnit();
589 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 613 GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
590 614
591 bool success = false; 615 bool success = false;
592 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 616 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
593 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() 617 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s()
594 SkASSERT(config == glTex->desc().fConfig); 618 SkASSERT(config == glTex->desc().fConfig);
595 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, false, left, 619 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, false, left,
596 top, width, height); 620 top, width, height);
597 } else { 621 } else {
(...skipping 2147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2745 int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1; 2769 int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1;
2746 if (lastUnitIdx != fHWActiveTextureUnitIdx) { 2770 if (lastUnitIdx != fHWActiveTextureUnitIdx) {
2747 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx)); 2771 GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
2748 fHWActiveTextureUnitIdx = lastUnitIdx; 2772 fHWActiveTextureUnitIdx = lastUnitIdx;
2749 } 2773 }
2750 // clear out the this field so that if a program does use this unit it will rebind the correct 2774 // clear out the this field so that if a program does use this unit it will rebind the correct
2751 // texture. 2775 // texture.
2752 fHWBoundTextureUniqueIDs[lastUnitIdx] = SK_InvalidUniqueID; 2776 fHWBoundTextureUniqueIDs[lastUnitIdx] = SK_InvalidUniqueID;
2753 } 2777 }
2754 2778
2755 namespace {
2756 // Determines whether glBlitFramebuffer could be used between src and dst. 2779 // Determines whether glBlitFramebuffer could be used between src and dst.
2757 inline bool can_blit_framebuffer(const GrSurface* dst, 2780 static inline bool can_blit_framebuffer(const GrSurface* dst,
2758 const GrSurface* src, 2781 const GrSurface* src,
2759 const GrGLGpu* gpu) { 2782 const GrGLGpu* gpu) {
2760 if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt > 0) && 2783 if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt > 0) &&
2761 gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) && 2784 gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) &&
2762 gpu->glCaps().usesMSAARenderBuffers()) { 2785 gpu->glCaps().usesMSAARenderBuffers()) {
2763 // ES3 doesn't allow framebuffer blits when the src has MSAA and the con figs don't match 2786 // ES3 doesn't allow framebuffer blits when the src has MSAA and the con figs don't match
2764 // or the rects are not the same (not just the same size but have the sa me edges). 2787 // or the rects are not the same (not just the same size but have the sa me edges).
2765 if (GrGLCaps::kES_3_0_MSFBOType == gpu->glCaps().msFBOType() && 2788 if (GrGLCaps::kES_3_0_MSFBOType == gpu->glCaps().msFBOType() &&
2766 (src->desc().fSampleCnt > 0 || src->config() != dst->config())) { 2789 (src->desc().fSampleCnt > 0 || src->config() != dst->config())) {
2767 return false; 2790 return false;
2768 } 2791 }
2792 const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTextu re());
2793 if (dstTex && dstTex->target() != GR_GL_TEXTURE_2D) {
2794 return false;
2795 }
2796 const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(dst->asTextu re());
2797 if (srcTex && srcTex->target() != GR_GL_TEXTURE_2D) {
2798 return false;
2799 }
2769 return true; 2800 return true;
2770 } else { 2801 } else {
2771 return false; 2802 return false;
2772 } 2803 }
2773 } 2804 }
2774 2805
2775 inline bool can_copy_texsubimage(const GrSurface* dst, 2806 static inline bool can_copy_texsubimage(const GrSurface* dst,
2776 const GrSurface* src, 2807 const GrSurface* src,
2777 const GrGLGpu* gpu) { 2808 const GrGLGpu* gpu) {
2778 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub Image 2809 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub Image
2779 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps 2810 // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2780 // many drivers would allow it to work, but ANGLE does not. 2811 // many drivers would allow it to work, but ANGLE does not.
2781 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF ormat() && 2812 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF ormat() &&
2782 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig = = src->config())) { 2813 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig = = src->config())) {
2783 return false; 2814 return false;
2784 } 2815 }
2785 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as RenderTarget()); 2816 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as RenderTarget());
2786 // If dst is multisampled (and uses an extension where there is a separate M SAA renderbuffer) 2817 // If dst is multisampled (and uses an extension where there is a separate M SAA renderbuffer)
2787 // then we don't want to copy to the texture but to the MSAA buffer. 2818 // then we don't want to copy to the texture but to the MSAA buffer.
2788 if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { 2819 if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) {
2789 return false; 2820 return false;
2790 } 2821 }
2791 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as RenderTarget()); 2822 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as RenderTarget());
2792 // If the src is multisampled (and uses an extension where there is a separa te MSAA 2823 // If the src is multisampled (and uses an extension where there is a separa te MSAA
2793 // renderbuffer) then it is an invalid operation to call CopyTexSubImage 2824 // renderbuffer) then it is an invalid operation to call CopyTexSubImage
2794 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { 2825 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
2795 return false; 2826 return false;
2796 } 2827 }
2828
2829 const GrGLTexture* dstTex = static_cast<const GrGLTexture*>(dst->asTexture() );
2830 // CopyTex(Sub)Image writes to a texture and we have no way of dynamically w rapping a RT in a
2831 // texture.
2832 if (!dstTex) {
2833 return false;
2834 }
2835
2836 const GrGLTexture* srcTex = static_cast<const GrGLTexture*>(src->asTexture() );
2837
2838 // Check that we could wrap the source in an FBO, that the dst is TEXTURE_2D , that no mirroring
2839 // is required.
2797 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) && 2840 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) &&
2798 dst->asTexture() && 2841 !GrPixelConfigIsCompressed(src->config()) &&
2799 dst->origin() == src->origin() && 2842 (!srcTex || srcTex->target() == GR_GL_TEXTURE_2D) &&
2800 !GrPixelConfigIsCompressed(src->config())) { 2843 dstTex->target() == GR_GL_TEXTURE_2D &&
2844 dst->origin() == src->origin()) {
2801 return true; 2845 return true;
2802 } else { 2846 } else {
2803 return false; 2847 return false;
2804 } 2848 }
2805 } 2849 }
2806 2850
2807 }
2808
2809 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha t the copy rect is 2851 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha t the copy rect is
2810 // relative to is output. 2852 // relative to is output.
2811 void GrGLGpu::bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGL IRect* viewport, 2853 void GrGLGpu::bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGL IRect* viewport,
2812 TempFBOTarget tempFBOTarget) { 2854 TempFBOTarget tempFBOTarget) {
2813 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge t()); 2855 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge t());
2814 if (nullptr == rt) { 2856 if (nullptr == rt) {
2815 SkASSERT(surface->asTexture()); 2857 SkASSERT(surface->asTexture());
2816 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur eID(); 2858 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur eID();
2817 GrGLenum target = static_cast<GrGLTexture*>(surface->asTexture())->targe t(); 2859 GrGLenum target = static_cast<GrGLTexture*>(surface->asTexture())->targe t();
2818 GrGLuint* tempFBOID; 2860 GrGLuint* tempFBOID;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2856 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const { 2898 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const {
2857 // If the src is a texture, we can implement the blit as a draw assuming the config is 2899 // If the src is a texture, we can implement the blit as a draw assuming the config is
2858 // renderable. 2900 // renderable.
2859 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals e)) { 2901 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals e)) {
2860 desc->fOrigin = kDefault_GrSurfaceOrigin; 2902 desc->fOrigin = kDefault_GrSurfaceOrigin;
2861 desc->fFlags = kRenderTarget_GrSurfaceFlag; 2903 desc->fFlags = kRenderTarget_GrSurfaceFlag;
2862 desc->fConfig = src->config(); 2904 desc->fConfig = src->config();
2863 return true; 2905 return true;
2864 } 2906 }
2865 2907
2908 const GrGLTexture* srcTexture = static_cast<const GrGLTexture*>(src->asTextu re());
2909 if (srcTexture && srcTexture->target() != GR_GL_TEXTURE_2D) {
2910 // Not supported for FBO blit or CopyTexSubImage
2911 return false;
2912 }
2913
2866 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are 2914 // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
2867 // possible and we return false to fallback to creating a render target dst for render-to- 2915 // possible and we return false to fallback to creating a render target dst for render-to-
2868 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger ing temporary fbo 2916 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger ing temporary fbo
2869 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal. 2917 // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
2870 2918
2871 // Check for format issues with glCopyTexSubImage2D 2919 // Check for format issues with glCopyTexSubImage2D
2872 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna lFormat() && 2920 if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInterna lFormat() &&
2873 kBGRA_8888_GrPixelConfig == src->config()) { 2921 kBGRA_8888_GrPixelConfig == src->config()) {
2874 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit 2922 // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
2875 // then we set up for that, otherwise fail. 2923 // then we set up for that, otherwise fail.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 } 2968 }
2921 2969
2922 if (can_blit_framebuffer(dst, src, this)) { 2970 if (can_blit_framebuffer(dst, src, this)) {
2923 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); 2971 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
2924 } 2972 }
2925 2973
2926 return false; 2974 return false;
2927 } 2975 }
2928 2976
2929 2977
2930 void GrGLGpu::createCopyProgram() { 2978 void GrGLGpu::createCopyPrograms() {
2979 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
2980 fCopyPrograms[i].fProgram = 0;
2981 }
2931 const char* version = this->glCaps().glslCaps()->versionDeclString(); 2982 const char* version = this->glCaps().glslCaps()->versionDeclString();
2983 static const GrSLType kSamplerTypes[2] = { kSampler2D_GrSLType, kSamplerExte rnal_GrSLType };
2984 SkASSERT(2 == SK_ARRAY_COUNT(fCopyPrograms));
2985 int programCount = this->glCaps().externalTextureSupport() ? 2 : 1;
2986 for (int i = 0; i < programCount; ++i) {
2987 GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttri bute_TypeModifier);
2988 GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
2989 GrShaderVar::kUniform_TypeModifier);
2990 GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType,
2991 GrShaderVar::kUniform_TypeModifier);
2992 GrGLSLShaderVar uTexture("u_texture", kSamplerTypes[i],
2993 GrShaderVar::kUniform_TypeModifier);
2994 GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType,
2995 GrShaderVar::kVaryingOut_TypeModifier);
2996 GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType,
2997 GrShaderVar::kOut_TypeModifier);
2998
2999 SkString vshaderTxt(version);
3000 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
3001 vshaderTxt.append(";");
3002 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
3003 vshaderTxt.append(";");
3004 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
3005 vshaderTxt.append(";");
3006 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
3007 vshaderTxt.append(";");
3008
3009 vshaderTxt.append(
3010 "// Copy Program VS\n"
3011 "void main() {"
3012 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z w;"
3013 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
3014 " gl_Position.zw = vec2(0, 1);"
3015 "}"
3016 );
2932 3017
2933 GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute _TypeModifier); 3018 SkString fshaderTxt(version);
2934 GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, 3019 if (kSamplerTypes[i] == kSamplerExternal_GrSLType) {
2935 GrShaderVar::kUniform_TypeModifier); 3020 fshaderTxt.appendf("#extension %s : require\n",
2936 GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); 3021 this->glCaps().glslCaps()->externalTextureExtensi onString());
2937 GrGLSLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUni form_TypeModifier); 3022 }
2938 GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVaryi ngOut_TypeModifier); 3023 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
2939 GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut _TypeModifier); 3024 *this->glCaps().glslCaps(),
3025 &fshaderTxt);
3026 vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
3027 vTexCoord.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
3028 fshaderTxt.append(";");
3029 uTexture.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
3030 fshaderTxt.append(";");
3031 const char* fsOutName;
3032 if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) {
3033 oFragColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
3034 fshaderTxt.append(";");
3035 fsOutName = oFragColor.c_str();
3036 } else {
3037 fsOutName = "gl_FragColor";
3038 }
3039 fshaderTxt.appendf(
3040 "// Copy Program FS\n"
3041 "void main() {"
3042 " %s = %s(u_texture, v_texCoord);"
3043 "}",
3044 fsOutName,
3045 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
3046 );
2940 3047
2941 SkString vshaderTxt(version); 3048 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram());
2942 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3049 const char* str;
2943 vshaderTxt.append(";"); 3050 GrGLint length;
2944 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2945 vshaderTxt.append(";");
2946 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2947 vshaderTxt.append(";");
2948 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2949 vshaderTxt.append(";");
2950
2951 vshaderTxt.append(
2952 "// Copy Program VS\n"
2953 "void main() {"
2954 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
2955 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
2956 " gl_Position.zw = vec2(0, 1);"
2957 "}"
2958 );
2959 3051
2960 SkString fshaderTxt(version); 3052 str = vshaderTxt.c_str();
2961 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, 3053 length = SkToInt(vshaderTxt.size());
2962 *this->glCaps().glslCaps(), 3054 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms [i].fProgram,
2963 &fshaderTxt); 3055 GR_GL_VERTEX_SHADER, &str, &length, 1,
2964 vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier); 3056 &fStats);
2965 vTexCoord.appendDecl(this->glCaps().glslCaps(), &fshaderTxt); 3057
2966 fshaderTxt.append(";"); 3058 str = fshaderTxt.c_str();
2967 uTexture.appendDecl(this->glCaps().glslCaps(), &fshaderTxt); 3059 length = SkToInt(fshaderTxt.size());
2968 fshaderTxt.append(";"); 3060 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms [i].fProgram,
2969 const char* fsOutName; 3061 GR_GL_FRAGMENT_SHADER, &st r, &length, 1,
2970 if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) { 3062 &fStats);
2971 oFragColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt); 3063
2972 fshaderTxt.append(";"); 3064 GL_CALL(LinkProgram(fCopyPrograms[i].fProgram));
2973 fsOutName = oFragColor.c_str(); 3065
2974 } else { 3066 GL_CALL_RET(fCopyPrograms[i].fTextureUniform,
2975 fsOutName = "gl_FragColor"; 3067 GetUniformLocation(fCopyPrograms[i].fProgram, "u_texture"));
3068 GL_CALL_RET(fCopyPrograms[i].fPosXformUniform,
3069 GetUniformLocation(fCopyPrograms[i].fProgram, "u_posXform")) ;
3070 GL_CALL_RET(fCopyPrograms[i].fTexCoordXformUniform,
3071 GetUniformLocation(fCopyPrograms[i].fProgram, "u_texCoordXfo rm"));
3072
3073 GL_CALL(BindAttribLocation(fCopyPrograms[i].fProgram, 0, "a_vertex"));
3074
3075 GL_CALL(DeleteShader(vshader));
3076 GL_CALL(DeleteShader(fshader));
2976 } 3077 }
2977 fshaderTxt.appendf(
2978 "// Copy Program FS\n"
2979 "void main() {"
2980 " %s = %s(u_texture, v_texCoord);"
2981 "}",
2982 fsOutName,
2983 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
2984 );
2985
2986 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram());
2987 const char* str;
2988 GrGLint length;
2989 3078
2990 str = vshaderTxt.c_str(); 3079 GL_CALL(GenBuffers(1, &fCopyProgramArrayBuffer));
2991 length = SkToInt(vshaderTxt.size()); 3080 fHWGeometryState.setVertexBufferID(this, fCopyProgramArrayBuffer);
2992 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram,
2993 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats);
2994
2995 str = fshaderTxt.c_str();
2996 length = SkToInt(fshaderTxt.size());
2997 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram,
2998 GR_GL_FRAGMENT_SHADER, &str, & length, 1, &fStats);
2999
3000 GL_CALL(LinkProgram(fCopyProgram.fProgram));
3001
3002 GL_CALL_RET(fCopyProgram.fTextureUniform, GetUniformLocation(fCopyProgram.fP rogram,
3003 "u_texture"));
3004 GL_CALL_RET(fCopyProgram.fPosXformUniform, GetUniformLocation(fCopyProgram.f Program,
3005 "u_posXform")) ;
3006 GL_CALL_RET(fCopyProgram.fTexCoordXformUniform, GetUniformLocation(fCopyProg ram.fProgram,
3007 "u_texCoo rdXform"));
3008
3009 GL_CALL(BindAttribLocation(fCopyProgram.fProgram, 0, "a_vertex"));
3010
3011 GL_CALL(DeleteShader(vshader));
3012 GL_CALL(DeleteShader(fshader));
3013
3014 GL_CALL(GenBuffers(1, &fCopyProgram.fArrayBuffer));
3015 fHWGeometryState.setVertexBufferID(this, fCopyProgram.fArrayBuffer);
3016 static const GrGLfloat vdata[] = { 3081 static const GrGLfloat vdata[] = {
3017 0, 0, 3082 0, 0,
3018 0, 1, 3083 0, 1,
3019 1, 0, 3084 1, 0,
3020 1, 1 3085 1, 1
3021 }; 3086 };
3022 GL_ALLOC_CALL(this->glInterface(), 3087 GL_ALLOC_CALL(this->glInterface(),
3023 BufferData(GR_GL_ARRAY_BUFFER, 3088 BufferData(GR_GL_ARRAY_BUFFER,
3024 (GrGLsizeiptr) sizeof(vdata), 3089 (GrGLsizeiptr) sizeof(vdata),
3025 vdata, // data ptr 3090 vdata, // data ptr
3026 GR_GL_STATIC_DRAW)); 3091 GR_GL_STATIC_DRAW));
3027 } 3092 }
3028 3093
3029 void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, 3094 void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
3030 GrSurface* src, 3095 GrSurface* src,
3031 const SkIRect& srcRect, 3096 const SkIRect& srcRect,
3032 const SkIPoint& dstPoint) { 3097 const SkIPoint& dstPoint) {
3033 int w = srcRect.width(); 3098 int w = srcRect.width();
3034 int h = srcRect.height(); 3099 int h = srcRect.height();
3035 3100
3036 GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture()); 3101 GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
3037 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_Fil terMode); 3102 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_Fil terMode);
3038 this->bindTexture(0, params, srcTex); 3103 this->bindTexture(0, params, srcTex);
3039 3104
3040 GrGLRenderTarget* dstRT = static_cast<GrGLRenderTarget*>(dst->asRenderTarget ()); 3105 GrGLRenderTarget* dstRT = static_cast<GrGLRenderTarget*>(dst->asRenderTarget ());
3041 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h); 3106 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
3042 this->flushRenderTarget(dstRT, &dstRect); 3107 this->flushRenderTarget(dstRT, &dstRect);
3043 3108
3044 GL_CALL(UseProgram(fCopyProgram.fProgram)); 3109 int progIdx = TextureTargetToCopyProgramIdx(srcTex->target());
3045 fHWProgramID = fCopyProgram.fProgram; 3110
3111 GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram));
3112 fHWProgramID = fCopyPrograms[progIdx].fProgram;
3046 3113
3047 fHWGeometryState.setVertexArrayID(this, 0); 3114 fHWGeometryState.setVertexArrayID(this, 0);
3048 3115
3049 GrGLAttribArrayState* attribs = 3116 GrGLAttribArrayState* attribs =
3050 fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgram.fArrayBuffe r); 3117 fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgramArrayBuffer) ;
3051 attribs->set(this, 0, fCopyProgram.fArrayBuffer, 2, GR_GL_FLOAT, false, 3118 attribs->set(this, 0, fCopyProgramArrayBuffer, 2, GR_GL_FLOAT, false,
3052 2 * sizeof(GrGLfloat), 0); 3119 2 * sizeof(GrGLfloat), 0);
3053 attribs->disableUnusedArrays(this, 0x1); 3120 attribs->disableUnusedArrays(this, 0x1);
3054 3121
3055 // dst rect edges in NDC (-1 to 1) 3122 // dst rect edges in NDC (-1 to 1)
3056 int dw = dst->width(); 3123 int dw = dst->width();
3057 int dh = dst->height(); 3124 int dh = dst->height();
3058 GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f; 3125 GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
3059 GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f; 3126 GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
3060 GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f; 3127 GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
3061 GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f; 3128 GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
3062 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { 3129 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
3063 dy0 = -dy0; 3130 dy0 = -dy0;
3064 dy1 = -dy1; 3131 dy1 = -dy1;
3065 } 3132 }
3066 3133
3067 // src rect edges in normalized texture space (0 to 1) 3134 // src rect edges in normalized texture space (0 to 1)
3068 int sw = src->width(); 3135 int sw = src->width();
3069 int sh = src->height(); 3136 int sh = src->height();
3070 GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft / sw; 3137 GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft / sw;
3071 GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w) / sw; 3138 GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w) / sw;
3072 GrGLfloat sy0 = (GrGLfloat)srcRect.fTop / sh; 3139 GrGLfloat sy0 = (GrGLfloat)srcRect.fTop / sh;
3073 GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h) / sh; 3140 GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h) / sh;
3074 if (kBottomLeft_GrSurfaceOrigin == src->origin()) { 3141 if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
3075 sy0 = 1.f - sy0; 3142 sy0 = 1.f - sy0;
3076 sy1 = 1.f - sy1; 3143 sy1 = 1.f - sy1;
3077 } 3144 }
3078 3145
3079 GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0)); 3146 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
3080 GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0, sx0, sy0)); 3147 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
3081 GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0)); 3148 sx1 - sx0, sy1 - sy0, sx0, sy0));
3149 GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0));
3082 3150
3083 GrXferProcessor::BlendInfo blendInfo; 3151 GrXferProcessor::BlendInfo blendInfo;
3084 blendInfo.reset(); 3152 blendInfo.reset();
3085 this->flushBlend(blendInfo); 3153 this->flushBlend(blendInfo);
3086 this->flushColorWrite(true); 3154 this->flushColorWrite(true);
3087 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); 3155 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
3088 this->flushHWAAState(dstRT, false); 3156 this->flushHWAAState(dstRT, false);
3089 this->disableScissor(); 3157 this->disableScissor();
3090 GrStencilSettings stencil; 3158 GrStencilSettings stencil;
3091 stencil.setDisabled(); 3159 stencil.setDisabled();
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 this->setVertexArrayID(gpu, 0); 3393 this->setVertexArrayID(gpu, 0);
3326 } 3394 }
3327 int attrCount = gpu->glCaps().maxVertexAttributes(); 3395 int attrCount = gpu->glCaps().maxVertexAttributes();
3328 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3396 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3329 fDefaultVertexArrayAttribState.resize(attrCount); 3397 fDefaultVertexArrayAttribState.resize(attrCount);
3330 } 3398 }
3331 attribState = &fDefaultVertexArrayAttribState; 3399 attribState = &fDefaultVertexArrayAttribState;
3332 } 3400 }
3333 return attribState; 3401 return attribState;
3334 } 3402 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLInterface.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698