OLD | NEW |
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 // exceed the global cap will instead clear the buffer. | 50 // exceed the global cap will instead clear the buffer. |
51 static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; | 51 static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; |
52 static int s_currentResourceUsePixels = 0; | 52 static int s_currentResourceUsePixels = 0; |
53 static const float s_resourceAdjustedRatio = 0.5; | 53 static const float s_resourceAdjustedRatio = 0.5; |
54 | 54 |
55 static const bool s_allowContextEvictionOnCreate = true; | 55 static const bool s_allowContextEvictionOnCreate = true; |
56 static const int s_maxScaleAttempts = 3; | 56 static const int s_maxScaleAttempts = 3; |
57 | 57 |
58 class ScopedTextureUnit0BindingRestorer { | 58 class ScopedTextureUnit0BindingRestorer { |
59 public: | 59 public: |
60 ScopedTextureUnit0BindingRestorer(GraphicsContext3D* context, GLenum activeT
extureUnit, Platform3DObject textureUnitZeroId) | 60 ScopedTextureUnit0BindingRestorer(blink::WebGraphicsContext3D* context, GLen
um activeTextureUnit, Platform3DObject textureUnitZeroId) |
61 : m_context(context) | 61 : m_context(context) |
62 , m_oldActiveTextureUnit(activeTextureUnit) | 62 , m_oldActiveTextureUnit(activeTextureUnit) |
63 , m_oldTextureUnitZeroId(textureUnitZeroId) | 63 , m_oldTextureUnitZeroId(textureUnitZeroId) |
64 { | 64 { |
65 m_context->activeTexture(GL_TEXTURE0); | 65 m_context->activeTexture(GL_TEXTURE0); |
66 } | 66 } |
67 ~ScopedTextureUnit0BindingRestorer() | 67 ~ScopedTextureUnit0BindingRestorer() |
68 { | 68 { |
69 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); | 69 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); |
70 m_context->activeTexture(m_oldActiveTextureUnit); | 70 m_context->activeTexture(m_oldActiveTextureUnit); |
71 } | 71 } |
72 | 72 |
73 private: | 73 private: |
74 GraphicsContext3D* m_context; | 74 blink::WebGraphicsContext3D* m_context; |
75 GLenum m_oldActiveTextureUnit; | 75 GLenum m_oldActiveTextureUnit; |
76 Platform3DObject m_oldTextureUnitZeroId; | 76 Platform3DObject m_oldTextureUnitZeroId; |
77 }; | 77 }; |
78 | 78 |
79 PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, cons
t IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvictionManag
er> contextEvictionManager) | 79 PassRefPtr<DrawingBuffer> DrawingBuffer::create(blink::WebGraphicsContext3D* con
text, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvi
ctionManager> contextEvictionManager) |
80 { | 80 { |
81 bool multisampleSupported = context->supportsExtension("GL_ANGLE_framebuffer
_blit") | 81 RefPtr<GraphicsContext3D> contextSupport(GraphicsContext3D::createContextSup
port(context)); |
82 && context->supportsExtension("GL_ANGLE_framebuffer_multisample") | 82 |
83 && context->supportsExtension("GL_OES_rgb8_rgba8"); | 83 bool multisampleSupported = contextSupport->supportsExtension("GL_ANGLE_fram
ebuffer_blit") |
| 84 && contextSupport->supportsExtension("GL_ANGLE_framebuffer_multisample") |
| 85 && contextSupport->supportsExtension("GL_OES_rgb8_rgba8"); |
84 if (multisampleSupported) { | 86 if (multisampleSupported) { |
85 context->ensureExtensionEnabled("GL_ANGLE_framebuffer_blit"); | 87 contextSupport->ensureExtensionEnabled("GL_ANGLE_framebuffer_blit"); |
86 context->ensureExtensionEnabled("GL_ANGLE_framebuffer_multisample"); | 88 contextSupport->ensureExtensionEnabled("GL_ANGLE_framebuffer_multisample
"); |
87 context->ensureExtensionEnabled("GL_OES_rgb8_rgba8"); | 89 contextSupport->ensureExtensionEnabled("GL_OES_rgb8_rgba8"); |
88 } | 90 } |
89 bool packedDepthStencilSupported = context->supportsExtension("GL_OES_packed
_depth_stencil"); | 91 bool packedDepthStencilSupported = contextSupport->supportsExtension("GL_OES
_packed_depth_stencil"); |
90 if (packedDepthStencilSupported) | 92 if (packedDepthStencilSupported) |
91 context->ensureExtensionEnabled("GL_OES_packed_depth_stencil"); | 93 contextSupport->ensureExtensionEnabled("GL_OES_packed_depth_stencil"); |
92 | 94 |
93 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, si
ze, multisampleSupported, packedDepthStencilSupported, preserve, contextEviction
Manager)); | 95 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, co
ntextSupport.get(), size, multisampleSupported, packedDepthStencilSupported, pre
serve, contextEvictionManager)); |
94 return drawingBuffer.release(); | 96 return drawingBuffer.release(); |
95 } | 97 } |
96 | 98 |
97 DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, | 99 DrawingBuffer::DrawingBuffer(blink::WebGraphicsContext3D* context, |
98 const IntSize& size, | 100 GraphicsContext3D* contextSupport, |
99 bool multisampleExtensionSupported, | 101 const IntSize& size, |
100 bool packedDepthStencilExtensionSupported, | 102 bool multisampleExtensionSupported, |
101 PreserveDrawingBuffer preserve, | 103 bool packedDepthStencilExtensionSupported, |
102 PassRefPtr<ContextEvictionManager> contextEvictionM
anager) | 104 PreserveDrawingBuffer preserve, |
| 105 PassRefPtr<ContextEvictionManager> contextEvictionManager) |
103 : m_preserveDrawingBuffer(preserve) | 106 : m_preserveDrawingBuffer(preserve) |
104 , m_scissorEnabled(false) | 107 , m_scissorEnabled(false) |
105 , m_texture2DBinding(0) | 108 , m_texture2DBinding(0) |
106 , m_framebufferBinding(0) | 109 , m_framebufferBinding(0) |
107 , m_activeTextureUnit(GL_TEXTURE0) | 110 , m_activeTextureUnit(GL_TEXTURE0) |
108 , m_context(context) | 111 , m_context(context) |
| 112 , m_contextSupport(contextSupport) |
109 , m_size(-1, -1) | 113 , m_size(-1, -1) |
110 , m_multisampleExtensionSupported(multisampleExtensionSupported) | 114 , m_multisampleExtensionSupported(multisampleExtensionSupported) |
111 , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupporte
d) | 115 , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupporte
d) |
112 , m_fbo(0) | 116 , m_fbo(0) |
113 , m_colorBuffer(0) | 117 , m_colorBuffer(0) |
114 , m_frontColorBuffer(0) | 118 , m_frontColorBuffer(0) |
115 , m_depthStencilBuffer(0) | 119 , m_depthStencilBuffer(0) |
116 , m_depthBuffer(0) | 120 , m_depthBuffer(0) |
117 , m_stencilBuffer(0) | 121 , m_stencilBuffer(0) |
118 , m_multisampleFBO(0) | 122 , m_multisampleFBO(0) |
119 , m_multisampleColorBuffer(0) | 123 , m_multisampleColorBuffer(0) |
120 , m_contentsChanged(true) | 124 , m_contentsChanged(true) |
121 , m_contentsChangeCommitted(false) | 125 , m_contentsChangeCommitted(false) |
| 126 , m_layerComposited(false) |
122 , m_internalColorFormat(0) | 127 , m_internalColorFormat(0) |
123 , m_colorFormat(0) | 128 , m_colorFormat(0) |
124 , m_internalRenderbufferFormat(0) | 129 , m_internalRenderbufferFormat(0) |
125 , m_maxTextureSize(0) | 130 , m_maxTextureSize(0) |
| 131 , m_packAlignment(4) |
126 , m_contextEvictionManager(contextEvictionManager) | 132 , m_contextEvictionManager(contextEvictionManager) |
127 { | 133 { |
128 // Used by browser tests to detect the use of a DrawingBuffer. | 134 // Used by browser tests to detect the use of a DrawingBuffer. |
129 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); | 135 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); |
130 initialize(size); | 136 initialize(size); |
131 } | 137 } |
132 | 138 |
133 DrawingBuffer::~DrawingBuffer() | 139 DrawingBuffer::~DrawingBuffer() |
134 { | 140 { |
135 releaseResources(); | 141 releaseResources(); |
136 } | 142 } |
137 | 143 |
138 void DrawingBuffer::markContentsChanged() | 144 void DrawingBuffer::markContentsChanged() |
139 { | 145 { |
140 m_contentsChanged = true; | 146 m_contentsChanged = true; |
141 m_contentsChangeCommitted = false; | 147 m_contentsChangeCommitted = false; |
| 148 m_layerComposited = false; |
| 149 } |
| 150 |
| 151 bool DrawingBuffer::layerComposited() const |
| 152 { |
| 153 return m_layerComposited; |
| 154 } |
| 155 |
| 156 void DrawingBuffer::markLayerComposited() |
| 157 { |
| 158 m_layerComposited = true; |
142 } | 159 } |
143 | 160 |
144 blink::WebGraphicsContext3D* DrawingBuffer::context() | 161 blink::WebGraphicsContext3D* DrawingBuffer::context() |
145 { | 162 { |
146 if (!m_context) | 163 return m_context; |
147 return 0; | |
148 return m_context->webContext(); | |
149 } | 164 } |
150 | 165 |
151 bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
blink::WebExternalBitmap* bitmap) | 166 bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
blink::WebExternalBitmap* bitmap) |
152 { | 167 { |
153 if (!m_context || !m_contentsChanged) | 168 if (!m_context || !m_contentsChanged) |
154 return false; | 169 return false; |
155 | 170 |
156 m_context->makeContextCurrent(); | 171 m_context->makeContextCurrent(); |
157 | 172 |
158 // Resolve the multisampled buffer into m_colorBuffer texture. | 173 // Resolve the multisampled buffer into m_colorBuffer texture. |
159 if (multisample()) | 174 if (multisample()) |
160 commit(); | 175 commit(); |
161 | 176 |
162 if (bitmap) { | 177 if (bitmap) { |
163 bitmap->setSize(size()); | 178 bitmap->setSize(size()); |
164 | 179 |
165 unsigned char* pixels = bitmap->pixels(); | 180 unsigned char* pixels = bitmap->pixels(); |
166 bool needPremultiply = m_attributes.alpha && !m_attributes.premultiplied
Alpha; | 181 bool needPremultiply = m_attributes.alpha && !m_attributes.premultiplied
Alpha; |
167 GraphicsContext3D::AlphaOp op = needPremultiply ? GraphicsContext3D::Alp
haDoPremultiply : GraphicsContext3D::AlphaDoNothing; | 182 GraphicsContext3D::AlphaOp op = needPremultiply ? GraphicsContext3D::Alp
haDoPremultiply : GraphicsContext3D::AlphaDoNothing; |
168 if (pixels) | 183 if (pixels) |
169 m_context->readBackFramebuffer(pixels, size().width(), size().height
(), GraphicsContext3D::ReadbackSkia, op); | 184 readBackFramebuffer(pixels, size().width(), size().height(), Readbac
kSkia, op); |
170 } | 185 } |
171 | 186 |
172 // We must restore the texture binding since creating new textures, | 187 // We must restore the texture binding since creating new textures, |
173 // consuming and producing mailboxes changes it. | 188 // consuming and producing mailboxes changes it. |
174 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU
nit, m_texture2DBinding); | 189 ScopedTextureUnit0BindingRestorer restorer(m_context, m_activeTextureUnit, m
_texture2DBinding); |
175 | 190 |
176 // First try to recycle an old buffer. | 191 // First try to recycle an old buffer. |
177 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); | 192 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); |
178 | 193 |
179 // No buffer available to recycle, create a new one. | 194 // No buffer available to recycle, create a new one. |
180 if (!frontColorBufferMailbox) { | 195 if (!frontColorBufferMailbox) { |
181 unsigned newColorBuffer = createColorTexture(m_size); | 196 unsigned newColorBuffer = createColorTexture(m_size); |
182 // Bad things happened, abandon ship. | 197 // Bad things happened, abandon ship. |
183 if (!newColorBuffer) | 198 if (!newColorBuffer) |
184 return false; | 199 return false; |
185 | 200 |
186 frontColorBufferMailbox = createNewMailbox(newColorBuffer); | 201 frontColorBufferMailbox = createNewMailbox(newColorBuffer); |
187 } | 202 } |
188 | 203 |
189 if (m_preserveDrawingBuffer == Discard) { | 204 if (m_preserveDrawingBuffer == Discard) { |
190 swap(frontColorBufferMailbox->textureId, m_colorBuffer); | 205 swap(frontColorBufferMailbox->textureId, m_colorBuffer); |
191 // It appears safe to overwrite the context's framebuffer binding in the
Discard case since there will always be a | 206 // It appears safe to overwrite the context's framebuffer binding in the
Discard case since there will always be a |
192 // WebGLRenderingContext::clearIfComposited() call made before the next
draw call which restores the framebuffer binding. | 207 // WebGLRenderingContext::clearIfComposited() call made before the next
draw call which restores the framebuffer binding. |
193 // If this stops being true at some point, we should track the current f
ramebuffer binding in the DrawingBuffer and restore | 208 // If this stops being true at some point, we should track the current f
ramebuffer binding in the DrawingBuffer and restore |
194 // it after attaching the new back buffer here. | 209 // it after attaching the new back buffer here. |
195 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 210 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
196 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL
_TEXTURE_2D, m_colorBuffer, 0); | 211 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL
_TEXTURE_2D, m_colorBuffer, 0); |
197 } else { | 212 } else { |
198 m_context->webContext()->copyTextureCHROMIUM(GL_TEXTURE_2D, m_colorBuffe
r, frontColorBufferMailbox->textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 213 m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_colorBuffer, frontColorB
ufferMailbox->textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
199 } | 214 } |
200 | 215 |
201 if (multisample() && !m_framebufferBinding) | 216 if (multisample() && !m_framebufferBinding) |
202 bind(); | 217 bind(); |
203 else | 218 else |
204 restoreFramebufferBinding(); | 219 restoreFramebufferBinding(); |
205 | 220 |
206 m_contentsChanged = false; | 221 m_contentsChanged = false; |
207 | 222 |
208 context()->bindTexture(GL_TEXTURE_2D, frontColorBufferMailbox->textureId); | 223 m_context->bindTexture(GL_TEXTURE_2D, frontColorBufferMailbox->textureId); |
209 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, frontColorBufferMailbox->ma
ilbox.name); | 224 m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, frontColorBufferMailbox->ma
ilbox.name); |
210 context()->flush(); | 225 m_context->flush(); |
211 m_context->markLayerComposited(); | 226 markLayerComposited(); |
212 | 227 |
213 *outMailbox = frontColorBufferMailbox->mailbox; | 228 *outMailbox = frontColorBufferMailbox->mailbox; |
214 m_frontColorBuffer = frontColorBufferMailbox->textureId; | 229 m_frontColorBuffer = frontColorBufferMailbox->textureId; |
215 return true; | 230 return true; |
216 } | 231 } |
217 | 232 |
218 void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail
box) | 233 void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail
box) |
219 { | 234 { |
220 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { | 235 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { |
221 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; | 236 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; |
222 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name
))) { | 237 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name
))) { |
223 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; | 238 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; |
224 m_recycledMailboxes.prepend(mailboxInfo.release()); | 239 m_recycledMailboxes.prepend(mailboxInfo.release()); |
225 return; | 240 return; |
226 } | 241 } |
227 } | 242 } |
228 ASSERT_NOT_REACHED(); | 243 ASSERT_NOT_REACHED(); |
229 } | 244 } |
230 | 245 |
231 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox() | 246 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox() |
232 { | 247 { |
233 if (!m_context || m_recycledMailboxes.isEmpty()) | 248 if (!m_context || m_recycledMailboxes.isEmpty()) |
234 return PassRefPtr<MailboxInfo>(); | 249 return PassRefPtr<MailboxInfo>(); |
235 | 250 |
236 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); | 251 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); |
237 m_recycledMailboxes.removeLast(); | 252 m_recycledMailboxes.removeLast(); |
238 | 253 |
239 if (mailboxInfo->mailbox.syncPoint) { | 254 if (mailboxInfo->mailbox.syncPoint) { |
240 context()->waitSyncPoint(mailboxInfo->mailbox.syncPoint); | 255 m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint); |
241 mailboxInfo->mailbox.syncPoint = 0; | 256 mailboxInfo->mailbox.syncPoint = 0; |
242 } | 257 } |
243 | 258 |
244 context()->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureId); | 259 m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureId); |
245 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo->mailbox.name); | 260 m_context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo->mailbox.name); |
246 | 261 |
247 if (mailboxInfo->size != m_size) { | 262 if (mailboxInfo->size != m_size) { |
248 m_context->texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorForma
t, m_size.width(), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | 263 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, m_size.w
idth(), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
249 mailboxInfo->size = m_size; | 264 mailboxInfo->size = m_size; |
250 } | 265 } |
251 | 266 |
252 return mailboxInfo.release(); | 267 return mailboxInfo.release(); |
253 } | 268 } |
254 | 269 |
255 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned
textureId) | 270 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned
textureId) |
256 { | 271 { |
257 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); | 272 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); |
258 context()->genMailboxCHROMIUM(returnMailbox->mailbox.name); | 273 m_context->genMailboxCHROMIUM(returnMailbox->mailbox.name); |
259 returnMailbox->textureId = textureId; | 274 returnMailbox->textureId = textureId; |
260 returnMailbox->size = m_size; | 275 returnMailbox->size = m_size; |
261 m_textureMailboxes.append(returnMailbox); | 276 m_textureMailboxes.append(returnMailbox); |
262 return returnMailbox.release(); | 277 return returnMailbox.release(); |
263 } | 278 } |
264 | 279 |
265 void DrawingBuffer::initialize(const IntSize& size) | 280 void DrawingBuffer::initialize(const IntSize& size) |
266 { | 281 { |
267 ASSERT(m_context); | 282 ASSERT(m_context); |
268 m_attributes = m_context->getContextAttributes(); | 283 m_attributes = m_context->getContextAttributes(); |
(...skipping 17 matching lines...) Expand all Loading... |
286 | 301 |
287 m_fbo = m_context->createFramebuffer(); | 302 m_fbo = m_context->createFramebuffer(); |
288 | 303 |
289 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 304 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
290 m_colorBuffer = createColorTexture(); | 305 m_colorBuffer = createColorTexture(); |
291 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX
TURE_2D, m_colorBuffer, 0); | 306 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX
TURE_2D, m_colorBuffer, 0); |
292 createSecondaryBuffers(); | 307 createSecondaryBuffers(); |
293 reset(size); | 308 reset(size); |
294 } | 309 } |
295 | 310 |
296 bool DrawingBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3D
Object texture, GLenum internalFormat, GLenum destType, GLint level, bool premul
tiplyAlpha, bool flipY) | 311 bool DrawingBuffer::copyToPlatformTexture(GraphicsContext3D& contextSupport, Pla
tform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool
premultiplyAlpha, bool flipY) |
297 { | 312 { |
298 if (!m_context || !m_context->makeContextCurrent()) | 313 if (!m_context || !m_context->makeContextCurrent()) |
299 return false; | 314 return false; |
300 if (m_contentsChanged) { | 315 if (m_contentsChanged) { |
301 if (multisample()) { | 316 if (multisample()) { |
302 commit(); | 317 commit(); |
303 if (!m_framebufferBinding) | 318 if (!m_framebufferBinding) |
304 bind(); | 319 bind(); |
305 else | 320 else |
306 restoreFramebufferBinding(); | 321 restoreFramebufferBinding(); |
307 } | 322 } |
308 m_context->flush(); | 323 m_context->flush(); |
309 } | 324 } |
310 Platform3DObject sourceTexture = m_colorBuffer; | 325 Platform3DObject sourceTexture = m_colorBuffer; |
311 | 326 |
312 if (!context.makeContextCurrent()) | 327 blink::WebGraphicsContext3D* context = contextSupport.webContext(); |
| 328 |
| 329 if (!context->makeContextCurrent()) |
313 return false; | 330 return false; |
314 if (!context.supportsExtension("GL_CHROMIUM_copy_texture") || !context.suppo
rtsExtension("GL_CHROMIUM_flipy") | 331 if (!contextSupport.supportsExtension("GL_CHROMIUM_copy_texture") || !contex
tSupport.supportsExtension("GL_CHROMIUM_flipy") |
315 || !context.canUseCopyTextureCHROMIUM(internalFormat, destType, level)) | 332 || !contextSupport.canUseCopyTextureCHROMIUM(internalFormat, destType, l
evel)) |
316 return false; | 333 return false; |
317 | 334 |
318 bool unpackPremultiplyAlphaNeeded = false; | 335 bool unpackPremultiplyAlphaNeeded = false; |
319 bool unpackUnpremultiplyAlphaNeeded = false; | 336 bool unpackUnpremultiplyAlphaNeeded = false; |
320 if (m_attributes.alpha && m_attributes.premultipliedAlpha && !premultiplyAlp
ha) | 337 if (m_attributes.alpha && m_attributes.premultipliedAlpha && !premultiplyAlp
ha) |
321 unpackUnpremultiplyAlphaNeeded = true; | 338 unpackUnpremultiplyAlphaNeeded = true; |
322 else if (m_attributes.alpha && !m_attributes.premultipliedAlpha && premultip
lyAlpha) | 339 else if (m_attributes.alpha && !m_attributes.premultipliedAlpha && premultip
lyAlpha) |
323 unpackPremultiplyAlphaNeeded = true; | 340 unpackPremultiplyAlphaNeeded = true; |
324 | 341 |
325 context.pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, unpackUnpremul
tiplyAlphaNeeded); | 342 context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, unpackUnpremu
ltiplyAlphaNeeded); |
326 context.pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, unpackPremultipl
yAlphaNeeded); | 343 context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, unpackPremultip
lyAlphaNeeded); |
327 context.pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, flipY); | 344 context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, flipY); |
328 context.webContext()->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, text
ure, level, internalFormat, destType); | 345 context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, level, i
nternalFormat, destType); |
329 context.pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false); | 346 context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false); |
330 context.pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); | 347 context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); |
331 context.pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false); | 348 context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false); |
332 context.flush(); | 349 context->flush(); |
333 | 350 |
334 return true; | 351 return true; |
335 } | 352 } |
336 | 353 |
337 Platform3DObject DrawingBuffer::framebuffer() const | 354 Platform3DObject DrawingBuffer::framebuffer() const |
338 { | 355 { |
339 return m_fbo; | 356 return m_fbo; |
340 } | 357 } |
341 | 358 |
342 blink::WebLayer* DrawingBuffer::platformLayer() | 359 blink::WebLayer* DrawingBuffer::platformLayer() |
343 { | 360 { |
344 if (!m_context) | 361 if (!m_context) |
345 return 0; | 362 return 0; |
346 | 363 |
347 if (!m_layer) { | 364 if (!m_layer) { |
348 m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->crea
teExternalTextureLayer(this)); | 365 m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->crea
teExternalTextureLayer(this)); |
349 | 366 |
350 m_layer->setOpaque(!m_attributes.alpha); | 367 m_layer->setOpaque(!m_attributes.alpha); |
351 m_layer->setBlendBackgroundColor(m_attributes.alpha); | 368 m_layer->setBlendBackgroundColor(m_attributes.alpha); |
352 m_layer->setPremultipliedAlpha(m_attributes.premultipliedAlpha); | 369 m_layer->setPremultipliedAlpha(m_attributes.premultipliedAlpha); |
353 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 370 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
354 } | 371 } |
355 | 372 |
356 return m_layer->layer(); | 373 return m_layer->layer(); |
357 } | 374 } |
358 | 375 |
359 void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer) | 376 void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer) |
360 { | 377 { |
361 if (!m_context || !m_context->makeContextCurrent() || m_context->webContext(
)->getGraphicsResetStatusARB() != GL_NO_ERROR) | 378 if (!m_context || !m_context->makeContextCurrent() || m_context->getGraphics
ResetStatusARB() != GL_NO_ERROR) |
362 return; | 379 return; |
363 | 380 |
364 if (!imageBuffer) | 381 if (!imageBuffer) |
365 return; | 382 return; |
366 Platform3DObject tex = imageBuffer->getBackingTexture(); | 383 Platform3DObject tex = imageBuffer->getBackingTexture(); |
367 if (tex) { | 384 if (tex) { |
368 m_context->webContext()->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColor
Buffer, | 385 m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer, |
369 tex, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 386 tex, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
370 return; | 387 return; |
371 } | 388 } |
372 | 389 |
373 // Since the m_frontColorBuffer was produced and sent to the compositor, it
cannot be bound to an fbo. | 390 // Since the m_frontColorBuffer was produced and sent to the compositor, it
cannot be bound to an fbo. |
374 // We have to make a copy of it here and bind that copy instead. | 391 // We have to make a copy of it here and bind that copy instead. |
375 // FIXME: That's not true any more, provided we don't change texture | 392 // FIXME: That's not true any more, provided we don't change texture |
376 // parameters. | 393 // parameters. |
377 unsigned sourceTexture = createColorTexture(m_size); | 394 unsigned sourceTexture = createColorTexture(m_size); |
378 m_context->webContext()->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuff
er, sourceTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 395 m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer, sourceText
ure, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
379 | 396 |
380 // Since we're using the same context as WebGL, we have to restore any state
we change (in this case, just the framebuffer binding). | 397 // Since we're using the same context as WebGL, we have to restore any state
we change (in this case, just the framebuffer binding). |
381 // FIXME: The WebGLRenderingContext tracks the current framebuffer binding,
it would be slightly more efficient to use this value | 398 // FIXME: The WebGLRenderingContext tracks the current framebuffer binding,
it would be slightly more efficient to use this value |
382 // rather than querying it off of the context. | 399 // rather than querying it off of the context. |
383 GLint previousFramebuffer = 0; | 400 GLint previousFramebuffer = 0; |
384 m_context->getIntegerv(GL_FRAMEBUFFER_BINDING, &previousFramebuffer); | 401 m_context->getIntegerv(GL_FRAMEBUFFER_BINDING, &previousFramebuffer); |
385 | 402 |
386 Platform3DObject framebuffer = m_context->createFramebuffer(); | 403 Platform3DObject framebuffer = m_context->createFramebuffer(); |
387 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer); | 404 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer); |
388 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX
TURE_2D, sourceTexture, 0); | 405 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX
TURE_2D, sourceTexture, 0); |
389 | 406 |
390 m_context->paintFramebufferToCanvas(framebuffer, size().width(), size().heig
ht(), !m_attributes.premultipliedAlpha, imageBuffer); | 407 paintFramebufferToCanvas(framebuffer, size().width(), size().height(), !m_at
tributes.premultipliedAlpha, imageBuffer); |
391 m_context->deleteFramebuffer(framebuffer); | 408 m_context->deleteFramebuffer(framebuffer); |
392 m_context->deleteTexture(sourceTexture); | 409 m_context->deleteTexture(sourceTexture); |
393 | 410 |
394 m_context->bindFramebuffer(GL_FRAMEBUFFER, previousFramebuffer); | 411 m_context->bindFramebuffer(GL_FRAMEBUFFER, previousFramebuffer); |
395 } | 412 } |
396 | 413 |
397 void DrawingBuffer::clearPlatformLayer() | 414 void DrawingBuffer::clearPlatformLayer() |
398 { | 415 { |
399 if (m_layer) | 416 if (m_layer) |
400 m_layer->clearTexture(); | 417 m_layer->clearTexture(); |
(...skipping 23 matching lines...) Expand all Loading... |
424 | 441 |
425 if (m_stencilBuffer) | 442 if (m_stencilBuffer) |
426 m_context->deleteRenderbuffer(m_stencilBuffer); | 443 m_context->deleteRenderbuffer(m_stencilBuffer); |
427 | 444 |
428 if (m_multisampleFBO) | 445 if (m_multisampleFBO) |
429 m_context->deleteFramebuffer(m_multisampleFBO); | 446 m_context->deleteFramebuffer(m_multisampleFBO); |
430 | 447 |
431 if (m_fbo) | 448 if (m_fbo) |
432 m_context->deleteFramebuffer(m_fbo); | 449 m_context->deleteFramebuffer(m_fbo); |
433 | 450 |
434 m_context.clear(); | 451 m_contextSupport.clear(); |
| 452 m_context = 0; |
435 } | 453 } |
436 | 454 |
437 setSize(IntSize()); | 455 setSize(IntSize()); |
438 | 456 |
439 m_colorBuffer = 0; | 457 m_colorBuffer = 0; |
440 m_frontColorBuffer = 0; | 458 m_frontColorBuffer = 0; |
441 m_multisampleColorBuffer = 0; | 459 m_multisampleColorBuffer = 0; |
442 m_depthStencilBuffer = 0; | 460 m_depthStencilBuffer = 0; |
443 m_depthBuffer = 0; | 461 m_depthBuffer = 0; |
444 m_stencilBuffer = 0; | 462 m_stencilBuffer = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
463 unsigned offscreenColorTexture = m_context->createTexture(); | 481 unsigned offscreenColorTexture = m_context->createTexture(); |
464 if (!offscreenColorTexture) | 482 if (!offscreenColorTexture) |
465 return 0; | 483 return 0; |
466 | 484 |
467 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture); | 485 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture); |
468 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 486 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
469 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 487 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
470 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
; | 488 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
; |
471 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
; | 489 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
; |
472 if (!size.isEmpty()) | 490 if (!size.isEmpty()) |
473 m_context->texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorForma
t, size.width(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | 491 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.wid
th(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
474 | 492 |
475 return offscreenColorTexture; | 493 return offscreenColorTexture; |
476 } | 494 } |
477 | 495 |
478 void DrawingBuffer::createSecondaryBuffers() | 496 void DrawingBuffer::createSecondaryBuffers() |
479 { | 497 { |
480 // create a multisample FBO | 498 // create a multisample FBO |
481 if (multisample()) { | 499 if (multisample()) { |
482 m_multisampleFBO = m_context->createFramebuffer(); | 500 m_multisampleFBO = m_context->createFramebuffer(); |
483 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 501 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
484 m_multisampleColorBuffer = m_context->createRenderbuffer(); | 502 m_multisampleColorBuffer = m_context->createRenderbuffer(); |
485 } | 503 } |
486 } | 504 } |
487 | 505 |
488 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) | 506 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) |
489 { | 507 { |
490 // resize regular FBO | 508 // resize regular FBO |
491 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 509 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
492 | 510 |
493 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer); | 511 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer); |
494 m_context->texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, s
ize.width(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | 512 |
| 513 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width()
, size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
| 514 |
495 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX
TURE_2D, m_colorBuffer, 0); | 515 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX
TURE_2D, m_colorBuffer, 0); |
496 | 516 |
497 m_context->bindTexture(GL_TEXTURE_2D, 0); | 517 m_context->bindTexture(GL_TEXTURE_2D, 0); |
498 | 518 |
499 if (!multisample()) | 519 if (!multisample()) |
500 resizeDepthStencil(size); | 520 resizeDepthStencil(size); |
501 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP
LETE) | 521 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP
LETE) |
502 return false; | 522 return false; |
503 | 523 |
504 return true; | 524 return true; |
505 } | 525 } |
506 | 526 |
507 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) | 527 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) |
508 { | 528 { |
509 if (multisample()) { | 529 if (multisample()) { |
510 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 530 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
511 | 531 |
512 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); | 532 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); |
513 m_context->webContext()->renderbufferStorageMultisampleCHROMIUM(GL_RENDE
RBUFFER, m_sampleCount, m_internalRenderbufferFormat, size.width(), size.height(
)); | 533 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sam
pleCount, m_internalRenderbufferFormat, size.width(), size.height()); |
514 | 534 |
515 if (m_context->getError() == GL_OUT_OF_MEMORY) | 535 if (m_context->getError() == GL_OUT_OF_MEMORY) |
516 return false; | 536 return false; |
517 | 537 |
518 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, m_multisampleColorBuffer); | 538 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, m_multisampleColorBuffer); |
519 resizeDepthStencil(size); | 539 resizeDepthStencil(size); |
520 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_
COMPLETE) | 540 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_
COMPLETE) |
521 return false; | 541 return false; |
522 } | 542 } |
523 | 543 |
524 return true; | 544 return true; |
525 } | 545 } |
526 | 546 |
527 void DrawingBuffer::resizeDepthStencil(const IntSize& size) | 547 void DrawingBuffer::resizeDepthStencil(const IntSize& size) |
528 { | 548 { |
529 if (m_attributes.depth && m_attributes.stencil && m_packedDepthStencilExtens
ionSupported) { | 549 if (m_attributes.depth && m_attributes.stencil && m_packedDepthStencilExtens
ionSupported) { |
530 if (!m_depthStencilBuffer) | 550 if (!m_depthStencilBuffer) |
531 m_depthStencilBuffer = m_context->createRenderbuffer(); | 551 m_depthStencilBuffer = m_context->createRenderbuffer(); |
532 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 552 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); |
533 if (multisample()) | 553 if (multisample()) |
534 m_context->webContext()->renderbufferStorageMultisampleCHROMIUM(GL_R
ENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()
); | 554 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m
_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
535 else | 555 else |
536 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_
OES, size.width(), size.height()); | 556 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_
OES, size.width(), size.height()); |
537 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT
, GL_RENDERBUFFER, m_depthStencilBuffer); | 557 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT
, GL_RENDERBUFFER, m_depthStencilBuffer); |
538 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, m_depthStencilBuffer); | 558 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, m_depthStencilBuffer); |
539 } else { | 559 } else { |
540 if (m_attributes.depth) { | 560 if (m_attributes.depth) { |
541 if (!m_depthBuffer) | 561 if (!m_depthBuffer) |
542 m_depthBuffer = m_context->createRenderbuffer(); | 562 m_depthBuffer = m_context->createRenderbuffer(); |
543 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer); | 563 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer); |
544 if (multisample()) | 564 if (multisample()) |
545 m_context->webContext()->renderbufferStorageMultisampleCHROMIUM(
GL_RENDERBUFFER, m_sampleCount, GL_DEPTH_COMPONENT16, size.width(), size.height(
)); | 565 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE
R, m_sampleCount, GL_DEPTH_COMPONENT16, size.width(), size.height()); |
546 else | 566 else |
547 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONE
NT16, size.width(), size.height()); | 567 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONE
NT16, size.width(), size.height()); |
548 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHME
NT, GL_RENDERBUFFER, m_depthBuffer); | 568 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHME
NT, GL_RENDERBUFFER, m_depthBuffer); |
549 } | 569 } |
550 if (m_attributes.stencil) { | 570 if (m_attributes.stencil) { |
551 if (!m_stencilBuffer) | 571 if (!m_stencilBuffer) |
552 m_stencilBuffer = m_context->createRenderbuffer(); | 572 m_stencilBuffer = m_context->createRenderbuffer(); |
553 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer); | 573 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer); |
554 if (multisample()) | 574 if (multisample()) |
555 m_context->webContext()->renderbufferStorageMultisampleCHROMIUM(
GL_RENDERBUFFER, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); | 575 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE
R, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height()); |
556 else | 576 else |
557 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX
8, size.width(), size.height()); | 577 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX
8, size.width(), size.height()); |
558 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH
MENT, GL_RENDERBUFFER, m_stencilBuffer); | 578 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH
MENT, GL_RENDERBUFFER, m_stencilBuffer); |
559 } | 579 } |
560 } | 580 } |
561 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0); | 581 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0); |
562 } | 582 } |
563 | 583 |
564 | 584 |
565 | 585 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 m_context->makeContextCurrent(); | 722 m_context->makeContextCurrent(); |
703 | 723 |
704 if (m_multisampleFBO && !m_contentsChangeCommitted) { | 724 if (m_multisampleFBO && !m_contentsChangeCommitted) { |
705 m_context->bindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 725 m_context->bindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); |
706 m_context->bindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 726 m_context->bindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); |
707 | 727 |
708 if (m_scissorEnabled) | 728 if (m_scissorEnabled) |
709 m_context->disable(GL_SCISSOR_TEST); | 729 m_context->disable(GL_SCISSOR_TEST); |
710 | 730 |
711 // Use NEAREST, because there is no scale performed during the blit. | 731 // Use NEAREST, because there is no scale performed during the blit. |
712 m_context->webContext()->blitFramebufferCHROMIUM(x, y, width, height, x,
y, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); | 732 m_context->blitFramebufferCHROMIUM(x, y, width, height, x, y, width, hei
ght, GL_COLOR_BUFFER_BIT, GL_NEAREST); |
713 | 733 |
714 if (m_scissorEnabled) | 734 if (m_scissorEnabled) |
715 m_context->enable(GL_SCISSOR_TEST); | 735 m_context->enable(GL_SCISSOR_TEST); |
716 } | 736 } |
717 | 737 |
718 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 738 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
719 m_contentsChangeCommitted = true; | 739 m_contentsChangeCommitted = true; |
720 } | 740 } |
721 | 741 |
722 void DrawingBuffer::restoreFramebufferBinding() | 742 void DrawingBuffer::restoreFramebufferBinding() |
(...skipping 10 matching lines...) Expand all Loading... |
733 } | 753 } |
734 | 754 |
735 void DrawingBuffer::bind() | 755 void DrawingBuffer::bind() |
736 { | 756 { |
737 if (!m_context) | 757 if (!m_context) |
738 return; | 758 return; |
739 | 759 |
740 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleF
BO : m_fbo); | 760 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleF
BO : m_fbo); |
741 } | 761 } |
742 | 762 |
| 763 void DrawingBuffer::setPackAlignment(GLint param) |
| 764 { |
| 765 m_packAlignment = param; |
| 766 } |
| 767 |
| 768 void DrawingBuffer::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer) |
| 769 { |
| 770 paintFramebufferToCanvas(framebuffer(), size().width(), size().height(), !m_
attributes.premultipliedAlpha, imageBuffer); |
| 771 } |
| 772 |
| 773 PassRefPtr<Uint8ClampedArray> DrawingBuffer::paintRenderingResultsToImageData(in
t& width, int& height) |
| 774 { |
| 775 if (m_attributes.premultipliedAlpha) |
| 776 return 0; |
| 777 |
| 778 width = size().width(); |
| 779 height = size().height(); |
| 780 |
| 781 Checked<int, RecordOverflow> dataSize = 4; |
| 782 dataSize *= width; |
| 783 dataSize *= height; |
| 784 if (dataSize.hasOverflowed()) |
| 785 return 0; |
| 786 |
| 787 RefPtr<Uint8ClampedArray> pixels = Uint8ClampedArray::createUninitialized(wi
dth * height * 4); |
| 788 |
| 789 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer()); |
| 790 readBackFramebuffer(pixels->data(), width, height, ReadbackRGBA, GraphicsCon
text3D::AlphaDoNothing); |
| 791 flipVertically(pixels->data(), width, height); |
| 792 |
| 793 return pixels.release(); |
| 794 } |
| 795 |
| 796 void DrawingBuffer::paintFramebufferToCanvas(int framebuffer, int width, int hei
ght, bool premultiplyAlpha, ImageBuffer* imageBuffer) |
| 797 { |
| 798 unsigned char* pixels = 0; |
| 799 |
| 800 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); |
| 801 const SkBitmap* readbackBitmap = 0; |
| 802 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); |
| 803 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { |
| 804 // This is the fastest and most common case. We read back |
| 805 // directly into the canvas's backing store. |
| 806 readbackBitmap = canvasBitmap; |
| 807 m_resizingBitmap.reset(); |
| 808 } else { |
| 809 // We need to allocate a temporary bitmap for reading back the |
| 810 // pixel data. We will then use Skia to rescale this bitmap to |
| 811 // the size of the canvas's backing store. |
| 812 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { |
| 813 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); |
| 814 if (!m_resizingBitmap.allocPixels()) |
| 815 return; |
| 816 } |
| 817 readbackBitmap = &m_resizingBitmap; |
| 818 } |
| 819 |
| 820 // Read back the frame buffer. |
| 821 SkAutoLockPixels bitmapLock(*readbackBitmap); |
| 822 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); |
| 823 |
| 824 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer); |
| 825 readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ?
GraphicsContext3D::AlphaDoPremultiply : GraphicsContext3D::AlphaDoNothing); |
| 826 flipVertically(pixels, width, height); |
| 827 |
| 828 readbackBitmap->notifyPixelsChanged(); |
| 829 if (m_resizingBitmap.readyToDraw()) { |
| 830 // We need to draw the resizing bitmap into the canvas's backing store. |
| 831 SkCanvas canvas(*canvasBitmap); |
| 832 SkRect dst; |
| 833 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); |
| 834 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); |
| 835 } |
| 836 } |
| 837 |
| 838 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, int width, int he
ight, ReadbackOrder readbackOrder, GraphicsContext3D::AlphaOp op) |
| 839 { |
| 840 if (m_packAlignment > 4) |
| 841 m_context->pixelStorei(GL_PACK_ALIGNMENT, 1); |
| 842 m_context->readPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels
); |
| 843 if (m_packAlignment > 4) |
| 844 m_context->pixelStorei(GL_PACK_ALIGNMENT, m_packAlignment); |
| 845 |
| 846 size_t bufferSize = 4 * width * height; |
| 847 |
| 848 if (readbackOrder == ReadbackSkia) { |
| 849 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
| 850 // Swizzle red and blue channels to match SkBitmap's byte ordering. |
| 851 // TODO(kbr): expose GL_BGRA as extension. |
| 852 for (size_t i = 0; i < bufferSize; i += 4) { |
| 853 std::swap(pixels[i], pixels[i + 2]); |
| 854 } |
| 855 #endif |
| 856 } |
| 857 |
| 858 if (op == GraphicsContext3D::AlphaDoPremultiply) { |
| 859 for (size_t i = 0; i < bufferSize; i += 4) { |
| 860 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); |
| 861 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); |
| 862 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); |
| 863 } |
| 864 } else if (op != GraphicsContext3D::AlphaDoNothing) { |
| 865 ASSERT_NOT_REACHED(); |
| 866 } |
| 867 } |
| 868 |
| 869 void DrawingBuffer::flipVertically(uint8_t* framebuffer, int width, int height) |
| 870 { |
| 871 m_scanline.resize(width * 4); |
| 872 uint8* scanline = &m_scanline[0]; |
| 873 unsigned rowBytes = width * 4; |
| 874 unsigned count = height / 2; |
| 875 for (unsigned i = 0; i < count; i++) { |
| 876 uint8* rowA = framebuffer + i * rowBytes; |
| 877 uint8* rowB = framebuffer + (height - i - 1) * rowBytes; |
| 878 memcpy(scanline, rowB, rowBytes); |
| 879 memcpy(rowB, rowA, rowBytes); |
| 880 memcpy(rowA, scanline, rowBytes); |
| 881 } |
| 882 } |
| 883 |
| 884 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in
ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum
type, GLint unpackAlignment) |
| 885 { |
| 886 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4
|| unpackAlignment == 8); |
| 887 m_context->texImage2D(target, level, internalformat, width, height, border,
format, type, 0); |
| 888 } |
| 889 |
743 } // namespace WebCore | 890 } // namespace WebCore |
OLD | NEW |