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

Side by Side Diff: Source/platform/graphics/gpu/DrawingBuffer.cpp

Issue 1066643003: Removed arbitrary 4096 size limit on WebGL canvas backbuffers, Take 3 (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Only check if canvas area is > 4096 * 4096 Created 5 years, 8 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 | « Source/platform/graphics/gpu/DrawingBuffer.h ('k') | no next file » | 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 (c) 2010, Google Inc. All rights reserved. 2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #ifndef NDEBUG 47 #ifndef NDEBUG
48 #include "wtf/RefCountedLeakCounter.h" 48 #include "wtf/RefCountedLeakCounter.h"
49 #endif 49 #endif
50 50
51 namespace blink { 51 namespace blink {
52 52
53 namespace { 53 namespace {
54 54
55 const float s_resourceAdjustedRatio = 0.5; 55 const float s_resourceAdjustedRatio = 0.5;
56 56
57 // Drawing buffers with more pixels than this will be explicitly checked for out of memory errors upon creation
58 const int s_largeBufferSize = 4096 * 4096;
59
57 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, drawingBufferCounter, ("Dra wingBuffer")); 60 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, drawingBufferCounter, ("Dra wingBuffer"));
58 61
59 class ScopedTextureUnit0BindingRestorer { 62 class ScopedTextureUnit0BindingRestorer {
60 public: 63 public:
61 ScopedTextureUnit0BindingRestorer(WebGraphicsContext3D* context, GLenum acti veTextureUnit, Platform3DObject textureUnitZeroId) 64 ScopedTextureUnit0BindingRestorer(WebGraphicsContext3D* context, GLenum acti veTextureUnit, Platform3DObject textureUnitZeroId)
62 : m_context(context) 65 : m_context(context)
63 , m_oldActiveTextureUnit(activeTextureUnit) 66 , m_oldActiveTextureUnit(activeTextureUnit)
64 , m_oldTextureUnitZeroId(textureUnitZeroId) 67 , m_oldTextureUnitZeroId(textureUnitZeroId)
65 { 68 {
66 m_context->activeTexture(GL_TEXTURE0); 69 m_context->activeTexture(GL_TEXTURE0);
67 } 70 }
68 ~ScopedTextureUnit0BindingRestorer() 71 ~ScopedTextureUnit0BindingRestorer()
69 { 72 {
70 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); 73 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId);
71 m_context->activeTexture(m_oldActiveTextureUnit); 74 m_context->activeTexture(m_oldActiveTextureUnit);
72 } 75 }
73 76
74 private: 77 private:
75 WebGraphicsContext3D* m_context; 78 WebGraphicsContext3D* m_context;
76 GLenum m_oldActiveTextureUnit; 79 GLenum m_oldActiveTextureUnit;
77 Platform3DObject m_oldTextureUnitZeroId; 80 Platform3DObject m_oldTextureUnitZeroId;
78 }; 81 };
79 82
83 class ScopedConditionalErrorCache {
84 public:
85 ScopedConditionalErrorCache(WebGraphicsContext3D* context, bool active)
86 : m_context(context)
87 , m_active(active)
88 {
89 if (m_active) {
90 GLenum error = m_context->getError();
91 while (error != GL_NO_ERROR) {
92 m_cachedErrors.append(error);
93 error = m_context->getError();
94 // Avoid infinite looping if glGetError is behaving badly.
Ken Russell (switch to Gerrit) 2015/04/07 22:18:00 This won't affect the behavior of the product, onl
95 ASSERT(m_cachedErrors.size() < 100);
96 }
97 }
98 }
99
100 ~ScopedConditionalErrorCache()
101 {
102 while (m_cachedErrors.size()) {
103 m_context->synthesizeGLError(m_cachedErrors.first());
104 m_cachedErrors.remove(0);
105 }
106 }
107
108 bool consumeErrorIf(GLenum error)
109 {
110 if (m_active) {
111 GLenum nextError = m_context->getError();
112 if (error == GL_NO_ERROR)
113 return false;
114
115 if (nextError == error)
116 return true;
117
118 m_cachedErrors.append(nextError);
119 }
120 return false;
121 }
122
123 private:
124 WebGraphicsContext3D* m_context;
125 bool m_active;
126 Vector<GLenum> m_cachedErrors;
127 };
128
129 bool isLargeBuffer(const IntSize& size)
130 {
131 return s_largeBufferSize <= size.width() * size.height();
132 }
133
80 } // namespace 134 } // namespace
81 135
82 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, WebGraphicsContex t3D::Attributes requestedAttributes) 136 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, WebGraphicsContex t3D::Attributes requestedAttributes)
83 { 137 {
84 ASSERT(context); 138 ASSERT(context);
85 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.g et()); 139 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.g et());
86 if (!extensionsUtil) { 140 if (!extensionsUtil) {
87 // This might be the first time we notice that the WebGraphicsContext3D is lost. 141 // This might be the first time we notice that the WebGraphicsContext3D is lost.
88 return nullptr; 142 return nullptr;
89 } 143 }
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 } 667 }
614 } 668 }
615 669
616 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) 670 bool DrawingBuffer::resizeFramebuffer(const IntSize& size)
617 { 671 {
618 // resize regular FBO 672 // resize regular FBO
619 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 673 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
620 674
621 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId); 675 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId);
622 676
623 allocateTextureMemory(&m_colorBuffer, size); 677 if (!allocateTextureMemory(&m_colorBuffer, size))
678 return false;
624 679
625 if (m_multisampleMode == ImplicitResolve) 680 if (m_multisampleMode == ImplicitResolve)
626 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount); 681 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount);
627 else 682 else
628 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer.textureId, 0); 683 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer.textureId, 0);
629 684
630 m_context->bindTexture(GL_TEXTURE_2D, 0); 685 m_context->bindTexture(GL_TEXTURE_2D, 0);
631 686
632 if (m_multisampleMode != ExplicitResolve) 687 if (m_multisampleMode != ExplicitResolve) {
633 resizeDepthStencil(size); 688 if (!resizeDepthStencil(size))
689 return false;
690 }
634 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP LETE) 691 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP LETE)
635 return false; 692 return false;
636 693
637 return true; 694 return true;
638 } 695 }
639 696
640 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) 697 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size)
641 { 698 {
642 if (m_multisampleMode == ExplicitResolve) { 699 if (m_multisampleMode == ExplicitResolve) {
700 ScopedConditionalErrorCache errorCache(m_context.get(), isLargeBuffer(si ze));
701
643 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); 702 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
644 703
645 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); 704 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer);
646 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sam pleCount, m_internalRenderbufferFormat, size.width(), size.height()); 705 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sam pleCount, m_internalRenderbufferFormat, size.width(), size.height());
647 706
648 if (m_context->getError() == GL_OUT_OF_MEMORY) 707 if (errorCache.consumeErrorIf(GL_OUT_OF_MEMORY))
649 return false; 708 return false;
650 709
651 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleColorBuffer); 710 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleColorBuffer);
652 resizeDepthStencil(size); 711 if (!resizeDepthStencil(size))
712 return false;
653 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_ COMPLETE) 713 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_ COMPLETE)
654 return false; 714 return false;
655 } 715 }
656 716
657 return true; 717 return true;
658 } 718 }
659 719
660 void DrawingBuffer::resizeDepthStencil(const IntSize& size) 720 bool DrawingBuffer::resizeDepthStencil(const IntSize& size)
661 { 721 {
662 if (!m_requestedAttributes.depth && !m_requestedAttributes.stencil) 722 if (!m_requestedAttributes.depth && !m_requestedAttributes.stencil)
663 return; 723 return true;
724
725 ScopedConditionalErrorCache errorCache(m_context.get(), isLargeBuffer(size)) ;
664 726
665 if (m_packedDepthStencilExtensionSupported) { 727 if (m_packedDepthStencilExtensionSupported) {
666 if (!m_depthStencilBuffer) 728 if (!m_depthStencilBuffer)
667 m_depthStencilBuffer = m_context->createRenderbuffer(); 729 m_depthStencilBuffer = m_context->createRenderbuffer();
668 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); 730 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
669 if (m_multisampleMode == ImplicitResolve) 731 if (m_multisampleMode == ImplicitResolve)
670 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_samp leCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); 732 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_samp leCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
671 else if (m_multisampleMode == ExplicitResolve) 733 else if (m_multisampleMode == ExplicitResolve)
672 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m _sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); 734 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m _sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
673 else 735 else
(...skipping 20 matching lines...) Expand all
694 if (m_multisampleMode == ImplicitResolve) 756 if (m_multisampleMode == ImplicitResolve)
695 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_ sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); 757 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_ sampleCount, GL_STENCIL_INDEX8, size.width(), size.height());
696 else if (m_multisampleMode == ExplicitResolve) 758 else if (m_multisampleMode == ExplicitResolve)
697 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE R, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); 759 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE R, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height());
698 else 760 else
699 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX 8, size.width(), size.height()); 761 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX 8, size.width(), size.height());
700 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH MENT, GL_RENDERBUFFER, m_stencilBuffer); 762 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH MENT, GL_RENDERBUFFER, m_stencilBuffer);
701 } 763 }
702 } 764 }
703 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0); 765 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0);
766
767 if (errorCache.consumeErrorIf(GL_OUT_OF_MEMORY))
768 return false;
769
770 return true;
704 } 771 }
705 772
706 773
707 774
708 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) 775 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask)
709 { 776 {
710 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer. 777 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer.
711 if (m_multisampleFBO) { 778 if (m_multisampleFBO) {
712 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 779 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
713 m_context->clear(GL_COLOR_BUFFER_BIT); 780 m_context->clear(GL_COLOR_BUFFER_BIT);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 memcpy(rowA, scanline, rowBytes); 1023 memcpy(rowA, scanline, rowBytes);
957 } 1024 }
958 } 1025 }
959 1026
960 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) 1027 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment)
961 { 1028 {
962 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); 1029 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);
963 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); 1030 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0);
964 } 1031 }
965 1032
966 void DrawingBuffer::allocateTextureMemory(TextureInfo* info, const IntSize& size ) 1033 bool DrawingBuffer::allocateTextureMemory(TextureInfo* info, const IntSize& size )
967 { 1034 {
1035 ScopedConditionalErrorCache errorCache(m_context.get(), isLargeBuffer(size)) ;
1036
968 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) { 1037 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) {
969 deleteChromiumImageForTexture(info); 1038 deleteChromiumImageForTexture(info);
970 1039
971 info->imageId = m_context->createGpuMemoryBufferImageCHROMIUM(size.width (), size.height(), GL_RGBA, GC3D_SCANOUT_CHROMIUM); 1040 info->imageId = m_context->createGpuMemoryBufferImageCHROMIUM(size.width (), size.height(), GL_RGBA, GC3D_SCANOUT_CHROMIUM);
1041
1042 if (errorCache.consumeErrorIf(GL_OUT_OF_MEMORY))
1043 return false;
1044
972 if (info->imageId) { 1045 if (info->imageId) {
973 m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); 1046 m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId);
974 return; 1047 return true;
975 } 1048 }
976 } 1049 }
977 1050
978 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); 1051 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE);
1052
1053 if (errorCache.consumeErrorIf(GL_OUT_OF_MEMORY))
1054 return false;
1055
1056 return true;
979 } 1057 }
980 1058
981 void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info) 1059 void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info)
982 { 1060 {
983 if (info->imageId) { 1061 if (info->imageId) {
984 m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); 1062 m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId);
985 m_context->destroyImageCHROMIUM(info->imageId); 1063 m_context->destroyImageCHROMIUM(info->imageId);
986 info->imageId = 0; 1064 info->imageId = 0;
987 } 1065 }
988 } 1066 }
989 1067
990 } // namespace blink 1068 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/gpu/DrawingBuffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698