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

Side by Side Diff: sky/engine/platform/graphics/gpu/DrawingBuffer.cpp

Issue 1229113003: Remove some unneeded DEPS from //sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 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
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 #include "sky/engine/platform/graphics/gpu/DrawingBuffer.h"
33
34 #include <algorithm>
35 #include "gen/sky/platform/RuntimeEnabledFeatures.h"
36 #include "sky/engine/platform/TraceEvent.h"
37 #include "sky/engine/platform/graphics/ImageBuffer.h"
38 #include "sky/engine/platform/graphics/gpu/Extensions3DUtil.h"
39 #include "sky/engine/public/platform/Platform.h"
40 #include "sky/engine/public/platform/WebExternalBitmap.h"
41 #include "sky/engine/public/platform/WebExternalTextureLayer.h"
42 #include "sky/engine/public/platform/WebGraphicsContext3D.h"
43 #include "sky/engine/public/platform/WebGraphicsContext3DProvider.h"
44 #ifndef NDEBUG
45 #include "sky/engine/wtf/RefCountedLeakCounter.h"
46 #endif
47
48 namespace blink {
49
50 namespace {
51 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer crea tion and resize.
52 // When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() ca lls that would
53 // exceed the global cap will instead clear the buffer.
54 const int s_maximumResourceUsePixels = 16 * 1024 * 1024;
55 int s_currentResourceUsePixels = 0;
56 const float s_resourceAdjustedRatio = 0.5;
57
58 const bool s_allowContextEvictionOnCreate = true;
59 const int s_maxScaleAttempts = 3;
60
61 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, drawingBufferCounter, ("Dra wingBuffer"));
62
63 class ScopedTextureUnit0BindingRestorer {
64 public:
65 ScopedTextureUnit0BindingRestorer(WebGraphicsContext3D* context, GLenum acti veTextureUnit, Platform3DObject textureUnitZeroId)
66 : m_context(context)
67 , m_oldActiveTextureUnit(activeTextureUnit)
68 , m_oldTextureUnitZeroId(textureUnitZeroId)
69 {
70 m_context->activeTexture(GL_TEXTURE0);
71 }
72 ~ScopedTextureUnit0BindingRestorer()
73 {
74 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId);
75 m_context->activeTexture(m_oldActiveTextureUnit);
76 }
77
78 private:
79 WebGraphicsContext3D* m_context;
80 GLenum m_oldActiveTextureUnit;
81 Platform3DObject m_oldTextureUnitZeroId;
82 };
83
84 } // namespace
85
86 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, WebGraphicsContex t3D::Attributes requestedAttributes, PassRefPtr<ContextEvictionManager> contextE victionManager)
87 {
88 ASSERT(context);
89 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.g et());
90 if (!extensionsUtil) {
91 // This might be the first time we notice that the WebGraphicsContext3D is lost.
92 return nullptr;
93 }
94 bool multisampleSupported = extensionsUtil->supportsExtension("GL_CHROMIUM_f ramebuffer_multisample")
95 && extensionsUtil->supportsExtension("GL_OES_rgb8_rgba8");
96 if (multisampleSupported) {
97 extensionsUtil->ensureExtensionEnabled("GL_CHROMIUM_framebuffer_multisam ple");
98 extensionsUtil->ensureExtensionEnabled("GL_OES_rgb8_rgba8");
99 }
100 bool packedDepthStencilSupported = extensionsUtil->supportsExtension("GL_OES _packed_depth_stencil");
101 if (packedDepthStencilSupported)
102 extensionsUtil->ensureExtensionEnabled("GL_OES_packed_depth_stencil");
103
104 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, ex tensionsUtil.release(), multisampleSupported, packedDepthStencilSupported, prese rve, requestedAttributes, contextEvictionManager));
105 if (!drawingBuffer->initialize(size)) {
106 drawingBuffer->beginDestruction();
107 return PassRefPtr<DrawingBuffer>();
108 }
109 return drawingBuffer.release();
110 }
111
112 DrawingBuffer::DrawingBuffer(PassOwnPtr<WebGraphicsContext3D> context,
113 PassOwnPtr<Extensions3DUtil> extensionsUtil,
114 bool multisampleExtensionSupported,
115 bool packedDepthStencilExtensionSupported,
116 PreserveDrawingBuffer preserve,
117 WebGraphicsContext3D::Attributes requestedAttributes,
118 PassRefPtr<ContextEvictionManager> contextEvictionManager)
119 : m_preserveDrawingBuffer(preserve)
120 , m_scissorEnabled(false)
121 , m_texture2DBinding(0)
122 , m_framebufferBinding(0)
123 , m_activeTextureUnit(GL_TEXTURE0)
124 , m_context(context)
125 , m_extensionsUtil(extensionsUtil)
126 , m_size(-1, -1)
127 , m_requestedAttributes(requestedAttributes)
128 , m_multisampleExtensionSupported(multisampleExtensionSupported)
129 , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupporte d)
130 , m_fbo(0)
131 , m_depthStencilBuffer(0)
132 , m_depthBuffer(0)
133 , m_stencilBuffer(0)
134 , m_multisampleFBO(0)
135 , m_multisampleColorBuffer(0)
136 , m_contentsChanged(true)
137 , m_contentsChangeCommitted(false)
138 , m_layerComposited(false)
139 , m_multisampleMode(None)
140 , m_internalColorFormat(0)
141 , m_colorFormat(0)
142 , m_internalRenderbufferFormat(0)
143 , m_maxTextureSize(0)
144 , m_sampleCount(0)
145 , m_packAlignment(4)
146 , m_destructionInProgress(false)
147 , m_isHidden(false)
148 , m_contextEvictionManager(contextEvictionManager)
149 {
150 // Used by browser tests to detect the use of a DrawingBuffer.
151 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", TRACE_EVENT_SCOPE_ NAME_PROCESS);
152 #ifndef NDEBUG
153 drawingBufferCounter.increment();
154 #endif
155 }
156
157 DrawingBuffer::~DrawingBuffer()
158 {
159 ASSERT(m_destructionInProgress);
160 ASSERT(m_textureMailboxes.isEmpty());
161 m_layer.clear();
162 m_context.clear();
163 #ifndef NDEBUG
164 drawingBufferCounter.decrement();
165 #endif
166 }
167
168 void DrawingBuffer::markContentsChanged()
169 {
170 m_contentsChanged = true;
171 m_contentsChangeCommitted = false;
172 m_layerComposited = false;
173 }
174
175 bool DrawingBuffer::layerComposited() const
176 {
177 return m_layerComposited;
178 }
179
180 void DrawingBuffer::markLayerComposited()
181 {
182 m_layerComposited = true;
183 }
184
185 WebGraphicsContext3D* DrawingBuffer::context()
186 {
187 return m_context.get();
188 }
189
190 void DrawingBuffer::setIsHidden(bool hidden)
191 {
192 if (m_isHidden == hidden)
193 return;
194 m_isHidden = hidden;
195 if (m_isHidden)
196 freeRecycledMailboxes();
197 }
198
199 void DrawingBuffer::freeRecycledMailboxes()
200 {
201 if (m_recycledMailboxQueue.isEmpty())
202 return;
203 while (!m_recycledMailboxQueue.isEmpty())
204 deleteMailbox(m_recycledMailboxQueue.takeLast());
205 }
206
207 bool DrawingBuffer::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExt ernalBitmap* bitmap)
208 {
209 ASSERT(!m_isHidden);
210 if (!m_contentsChanged)
211 return false;
212
213 if (m_destructionInProgress) {
214 // It can be hit in the following sequence.
215 // 1. WebGL draws something.
216 // 2. The compositor begins the frame.
217 // 3. Javascript makes a context lost using WEBGL_lose_context extension .
218 // 4. Here.
219 return false;
220 }
221
222 // Resolve the multisampled buffer into m_colorBuffer texture.
223 if (m_multisampleMode != None)
224 commit();
225
226 if (bitmap) {
227 bitmap->setSize(size());
228
229 unsigned char* pixels = bitmap->pixels();
230 bool needPremultiply = m_actualAttributes.alpha && !m_actualAttributes.p remultipliedAlpha;
231 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing;
232 if (pixels)
233 readBackFramebuffer(pixels, size().width(), size().height(), Readbac kSkia, op);
234 }
235
236 // We must restore the texture binding since creating new textures,
237 // consuming and producing mailboxes changes it.
238 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding);
239
240 // First try to recycle an old buffer.
241 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox();
242
243 // No buffer available to recycle, create a new one.
244 if (!frontColorBufferMailbox) {
245 TextureInfo newTexture;
246 newTexture.textureId = createColorTexture();
247 allocateTextureMemory(&newTexture, m_size);
248 // Bad things happened, abandon ship.
249 if (!newTexture.textureId)
250 return false;
251
252 frontColorBufferMailbox = createNewMailbox(newTexture);
253 }
254
255 if (m_preserveDrawingBuffer == Discard) {
256 std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer);
257 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a
258 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding.
259 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore
260 // it after attaching the new back buffer here.
261 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
262 if (m_multisampleMode == ImplicitResolve)
263 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COL OR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount);
264 else
265 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D, m_colorBuffer.textureId, 0);
266 } else {
267 m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_colorBuffer.textureId, f rontColorBufferMailbox->textureInfo.textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE);
268 }
269
270 if (m_multisampleMode != None && !m_framebufferBinding)
271 bind();
272 else
273 restoreFramebufferBinding();
274
275 m_contentsChanged = false;
276
277 m_context->produceTextureDirectCHROMIUM(frontColorBufferMailbox->textureInfo .textureId, GL_TEXTURE_2D, frontColorBufferMailbox->mailbox.name);
278 m_context->flush();
279 frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
280 frontColorBufferMailbox->mailbox.allowOverlay = frontColorBufferMailbox->tex tureInfo.imageId != 0;
281 markLayerComposited();
282
283 // set m_parentDrawingBuffer to make sure 'this' stays alive as long as it h as live mailboxes
284 ASSERT(!frontColorBufferMailbox->m_parentDrawingBuffer);
285 frontColorBufferMailbox->m_parentDrawingBuffer = this;
286 *outMailbox = frontColorBufferMailbox->mailbox;
287 m_frontColorBuffer = frontColorBufferMailbox->textureInfo;
288 return true;
289 }
290
291 void DrawingBuffer::mailboxReleased(const WebExternalTextureMailbox& mailbox, bo ol lostResource)
292 {
293 if (m_destructionInProgress || m_context->isContextLost() || lostResource || m_isHidden) {
294 mailboxReleasedWithoutRecycling(mailbox);
295 return;
296 }
297
298 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
299 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i];
300 if (nameEquals(mailboxInfo->mailbox, mailbox)) {
301 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint;
302 ASSERT(mailboxInfo->m_parentDrawingBuffer.get() == this);
303 mailboxInfo->m_parentDrawingBuffer.clear();
304 m_recycledMailboxQueue.prepend(mailboxInfo->mailbox);
305 return;
306 }
307 }
308 ASSERT_NOT_REACHED();
309 }
310
311 void DrawingBuffer::mailboxReleasedWithoutRecycling(const WebExternalTextureMail box& mailbox)
312 {
313 ASSERT(m_textureMailboxes.size());
314 // Ensure not to call the destructor until deleteMailbox() is completed.
315 RefPtr<DrawingBuffer> self = this;
316 deleteMailbox(mailbox);
317 }
318
319 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
320 {
321 if (m_recycledMailboxQueue.isEmpty())
322 return PassRefPtr<MailboxInfo>();
323
324 WebExternalTextureMailbox mailbox;
325 while (!m_recycledMailboxQueue.isEmpty()) {
326 mailbox = m_recycledMailboxQueue.takeLast();
327 // Never have more than one mailbox in the released state.
328 if (!m_recycledMailboxQueue.isEmpty())
329 deleteMailbox(mailbox);
330 }
331
332 RefPtr<MailboxInfo> mailboxInfo;
333 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
334 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
335 mailboxInfo = m_textureMailboxes[i];
336 break;
337 }
338 }
339 ASSERT(mailboxInfo);
340
341 if (mailboxInfo->mailbox.syncPoint) {
342 m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint);
343 mailboxInfo->mailbox.syncPoint = 0;
344 }
345
346 if (mailboxInfo->size != m_size) {
347 m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureInfo.textureId );
348 allocateTextureMemory(&mailboxInfo->textureInfo, m_size);
349 mailboxInfo->size = m_size;
350 }
351
352 return mailboxInfo.release();
353 }
354
355 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const Tex tureInfo& info)
356 {
357 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo());
358 m_context->genMailboxCHROMIUM(returnMailbox->mailbox.name);
359 returnMailbox->textureInfo = info;
360 returnMailbox->size = m_size;
361 m_textureMailboxes.append(returnMailbox);
362 return returnMailbox.release();
363 }
364
365 void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox)
366 {
367 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
368 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
369 if (mailbox.syncPoint)
370 m_context->waitSyncPoint(mailbox.syncPoint);
371
372 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo);
373
374 m_context->deleteTexture(m_textureMailboxes[i]->textureInfo.textureI d);
375 m_textureMailboxes.remove(i);
376 return;
377 }
378 }
379 ASSERT_NOT_REACHED();
380 }
381
382 bool DrawingBuffer::initialize(const IntSize& size)
383 {
384 if (m_context->isContextLost()) {
385 // Need to try to restore the context again later.
386 return false;
387 }
388
389 if (m_requestedAttributes.alpha) {
390 m_internalColorFormat = GL_RGBA;
391 m_colorFormat = GL_RGBA;
392 m_internalRenderbufferFormat = GL_RGBA8_OES;
393 } else {
394 m_internalColorFormat = GL_RGB;
395 m_colorFormat = GL_RGB;
396 m_internalRenderbufferFormat = GL_RGB8_OES;
397 }
398
399 m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
400
401 int maxSampleCount = 0;
402 m_multisampleMode = None;
403 if (m_requestedAttributes.antialias && m_multisampleExtensionSupported) {
404 m_context->getIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount);
405 m_multisampleMode = ExplicitResolve;
406 if (m_extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_t exture"))
407 m_multisampleMode = ImplicitResolve;
408 }
409 m_sampleCount = std::min(4, maxSampleCount);
410
411 m_fbo = m_context->createFramebuffer();
412
413 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
414 m_colorBuffer.textureId = createColorTexture();
415 if (m_multisampleMode == ImplicitResolve)
416 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount);
417 else
418 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer.textureId, 0);
419 createSecondaryBuffers();
420 // We first try to initialize everything with the requested attributes.
421 if (!reset(size))
422 return false;
423 // If that succeeds, we then see what we actually got and update our actual attributes to reflect that.
424 m_actualAttributes = m_requestedAttributes;
425 if (m_requestedAttributes.alpha) {
426 WGC3Dint alphaBits = 0;
427 m_context->getIntegerv(GL_ALPHA_BITS, &alphaBits);
428 m_actualAttributes.alpha = alphaBits > 0;
429 }
430 if (m_requestedAttributes.depth) {
431 WGC3Dint depthBits = 0;
432 m_context->getIntegerv(GL_DEPTH_BITS, &depthBits);
433 m_actualAttributes.depth = depthBits > 0;
434 }
435 if (m_requestedAttributes.stencil) {
436 WGC3Dint stencilBits = 0;
437 m_context->getIntegerv(GL_STENCIL_BITS, &stencilBits);
438 m_actualAttributes.stencil = stencilBits > 0;
439 }
440 m_actualAttributes.antialias = multisample();
441 return true;
442 }
443
444 bool DrawingBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platfor m3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool pre multiplyAlpha, bool flipY, bool fromFrontBuffer)
445 {
446 GLint textureId = m_colorBuffer.textureId;
447 if (fromFrontBuffer && m_frontColorBuffer.textureId)
448 textureId = m_frontColorBuffer.textureId;
449
450 if (m_contentsChanged) {
451 if (m_multisampleMode != None) {
452 commit();
453 if (!m_framebufferBinding)
454 bind();
455 else
456 restoreFramebufferBinding();
457 }
458 m_context->flush();
459 }
460
461 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, l evel))
462 return false;
463
464 // Contexts may be in a different share group. We must transfer the texture through a mailbox first
465 RefPtr<MailboxInfo> bufferMailbox = adoptRef(new MailboxInfo());
466 m_context->genMailboxCHROMIUM(bufferMailbox->mailbox.name);
467 m_context->produceTextureDirectCHROMIUM(textureId, GL_TEXTURE_2D, bufferMail box->mailbox.name);
468 m_context->flush();
469
470 bufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
471
472 context->waitSyncPoint(bufferMailbox->mailbox.syncPoint);
473 Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIUM(GL _TEXTURE_2D, bufferMailbox->mailbox.name);
474
475 bool unpackPremultiplyAlphaNeeded = false;
476 bool unpackUnpremultiplyAlphaNeeded = false;
477 if (m_actualAttributes.alpha && m_actualAttributes.premultipliedAlpha && !pr emultiplyAlpha)
478 unpackUnpremultiplyAlphaNeeded = true;
479 else if (m_actualAttributes.alpha && !m_actualAttributes.premultipliedAlpha && premultiplyAlpha)
480 unpackPremultiplyAlphaNeeded = true;
481
482 context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, unpackUnpremu ltiplyAlphaNeeded);
483 context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, unpackPremultip lyAlphaNeeded);
484 context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, flipY);
485 context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, level, i nternalFormat, destType);
486 context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false);
487 context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
488 context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false);
489
490 context->deleteTexture(sourceTexture);
491
492 context->flush();
493 m_context->waitSyncPoint(context->insertSyncPoint());
494
495 return true;
496 }
497
498 Platform3DObject DrawingBuffer::framebuffer() const
499 {
500 return m_fbo;
501 }
502
503 WebLayer* DrawingBuffer::platformLayer()
504 {
505 if (!m_layer) {
506 m_layer = nullptr;
507 CRASH(); // No compositor.
508
509 m_layer->setOpaque(!m_actualAttributes.alpha);
510 m_layer->setBlendBackgroundColor(m_actualAttributes.alpha);
511 m_layer->setPremultipliedAlpha(m_actualAttributes.premultipliedAlpha);
512 }
513
514 return m_layer->layer();
515 }
516
517 void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer)
518 {
519 if (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR)
520 return;
521
522 if (!imageBuffer)
523 return;
524 Platform3DObject tex = imageBuffer->getBackingTexture();
525 if (tex) {
526 RefPtr<MailboxInfo> bufferMailbox = adoptRef(new MailboxInfo());
527 m_context->genMailboxCHROMIUM(bufferMailbox->mailbox.name);
528 m_context->produceTextureDirectCHROMIUM(m_frontColorBuffer.textureId, GL _TEXTURE_2D, bufferMailbox->mailbox.name);
529 m_context->flush();
530
531 bufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
532 OwnPtr<WebGraphicsContext3DProvider> provider =
533 adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3D Provider());
534 if (!provider)
535 return;
536 WebGraphicsContext3D* context = provider->context3d();
537 if (!context)
538 return;
539
540 context->waitSyncPoint(bufferMailbox->mailbox.syncPoint);
541 Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIU M(GL_TEXTURE_2D, bufferMailbox->mailbox.name);
542 context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture,
543 tex, 0, GL_RGBA, GL_UNSIGNED_BYTE);
544 context->deleteTexture(sourceTexture);
545 context->flush();
546 m_context->waitSyncPoint(context->insertSyncPoint());
547 return;
548 }
549
550 Platform3DObject framebuffer = m_context->createFramebuffer();
551 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
552 // We don't need to bind a copy of m_frontColorBuffer since the texture para meters are untouched.
553 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEX TURE_2D, m_frontColorBuffer.textureId, 0);
554
555 paintFramebufferToCanvas(framebuffer, size().width(), size().height(), !m_ac tualAttributes.premultipliedAlpha, imageBuffer);
556 m_context->deleteFramebuffer(framebuffer);
557 // Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding).
558 restoreFramebufferBinding();
559 }
560
561 void DrawingBuffer::clearPlatformLayer()
562 {
563 if (m_layer)
564 m_layer->clearTexture();
565
566 m_context->flush();
567 }
568
569 void DrawingBuffer::beginDestruction()
570 {
571 ASSERT(!m_destructionInProgress);
572 m_destructionInProgress = true;
573
574 clearPlatformLayer();
575
576 while (!m_recycledMailboxQueue.isEmpty())
577 deleteMailbox(m_recycledMailboxQueue.takeLast());
578
579 if (m_multisampleFBO)
580 m_context->deleteFramebuffer(m_multisampleFBO);
581
582 if (m_fbo)
583 m_context->deleteFramebuffer(m_fbo);
584
585 if (m_multisampleColorBuffer)
586 m_context->deleteRenderbuffer(m_multisampleColorBuffer);
587
588 if (m_depthStencilBuffer)
589 m_context->deleteRenderbuffer(m_depthStencilBuffer);
590
591 if (m_depthBuffer)
592 m_context->deleteRenderbuffer(m_depthBuffer);
593
594 if (m_stencilBuffer)
595 m_context->deleteRenderbuffer(m_stencilBuffer);
596
597 if (m_colorBuffer.textureId) {
598 deleteChromiumImageForTexture(&m_colorBuffer);
599 m_context->deleteTexture(m_colorBuffer.textureId);
600 }
601
602 setSize(IntSize());
603
604 m_colorBuffer = TextureInfo();
605 m_frontColorBuffer = TextureInfo();
606 m_multisampleColorBuffer = 0;
607 m_depthStencilBuffer = 0;
608 m_depthBuffer = 0;
609 m_stencilBuffer = 0;
610 m_multisampleFBO = 0;
611 m_fbo = 0;
612 m_contextEvictionManager.clear();
613 }
614
615 unsigned DrawingBuffer::createColorTexture()
616 {
617 unsigned offscreenColorTexture = m_context->createTexture();
618 if (!offscreenColorTexture)
619 return 0;
620
621 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture);
622 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
623 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
624 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ;
625 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ;
626
627 return offscreenColorTexture;
628 }
629
630 void DrawingBuffer::createSecondaryBuffers()
631 {
632 // create a multisample FBO
633 if (m_multisampleMode == ExplicitResolve) {
634 m_multisampleFBO = m_context->createFramebuffer();
635 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
636 m_multisampleColorBuffer = m_context->createRenderbuffer();
637 }
638 }
639
640 bool DrawingBuffer::resizeFramebuffer(const IntSize& size)
641 {
642 // resize regular FBO
643 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
644
645 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId);
646
647 allocateTextureMemory(&m_colorBuffer, size);
648
649 if (m_multisampleMode == ImplicitResolve)
650 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount);
651 else
652 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer.textureId, 0);
653
654 m_context->bindTexture(GL_TEXTURE_2D, 0);
655
656 if (m_multisampleMode != ExplicitResolve)
657 resizeDepthStencil(size);
658 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMP LETE)
659 return false;
660
661 return true;
662 }
663
664 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size)
665 {
666 if (m_multisampleMode == ExplicitResolve) {
667 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
668
669 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer);
670 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sam pleCount, m_internalRenderbufferFormat, size.width(), size.height());
671
672 if (m_context->getError() == GL_OUT_OF_MEMORY)
673 return false;
674
675 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_multisampleColorBuffer);
676 resizeDepthStencil(size);
677 if (m_context->checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_ COMPLETE)
678 return false;
679 }
680
681 return true;
682 }
683
684 void DrawingBuffer::resizeDepthStencil(const IntSize& size)
685 {
686 if (!m_requestedAttributes.depth && !m_requestedAttributes.stencil)
687 return;
688
689 if (m_packedDepthStencilExtensionSupported) {
690 if (!m_depthStencilBuffer)
691 m_depthStencilBuffer = m_context->createRenderbuffer();
692 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
693 if (m_multisampleMode == ImplicitResolve)
694 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_samp leCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
695 else if (m_multisampleMode == ExplicitResolve)
696 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m _sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height());
697 else
698 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_ OES, size.width(), size.height());
699 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER, m_depthStencilBuffer);
700 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
701 } else {
702 if (m_requestedAttributes.depth) {
703 if (!m_depthBuffer)
704 m_depthBuffer = m_context->createRenderbuffer();
705 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
706 if (m_multisampleMode == ImplicitResolve)
707 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_ sampleCount, GL_DEPTH_COMPONENT16, size.width(), size.height());
708 else if (m_multisampleMode == ExplicitResolve)
709 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE R, m_sampleCount, GL_DEPTH_COMPONENT16, size.width(), size.height());
710 else
711 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONE NT16, size.width(), size.height());
712 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHME NT, GL_RENDERBUFFER, m_depthBuffer);
713 }
714 if (m_requestedAttributes.stencil) {
715 if (!m_stencilBuffer)
716 m_stencilBuffer = m_context->createRenderbuffer();
717 m_context->bindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
718 if (m_multisampleMode == ImplicitResolve)
719 m_context->renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_ sampleCount, GL_STENCIL_INDEX8, size.width(), size.height());
720 else if (m_multisampleMode == ExplicitResolve)
721 m_context->renderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFE R, m_sampleCount, GL_STENCIL_INDEX8, size.width(), size.height());
722 else
723 m_context->renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX 8, size.width(), size.height());
724 m_context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACH MENT, GL_RENDERBUFFER, m_stencilBuffer);
725 }
726 }
727 m_context->bindRenderbuffer(GL_RENDERBUFFER, 0);
728 }
729
730
731
732 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask)
733 {
734 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer.
735 if (m_multisampleFBO) {
736 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
737 m_context->clear(GL_COLOR_BUFFER_BIT);
738 }
739
740 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleF BO : m_fbo);
741 m_context->clear(clearMask);
742 }
743
744 void DrawingBuffer::setSize(const IntSize& size)
745 {
746 if (m_size == size)
747 return;
748
749 s_currentResourceUsePixels += pixelDelta(size, m_size);
750 m_size = size;
751 }
752
753 int DrawingBuffer::pixelDelta(const IntSize& newSize, const IntSize& curSize)
754 {
755 return (std::max(0, newSize.width()) * std::max(0, newSize.height())) - (std ::max(0, curSize.width()) * std::max(0, curSize.height()));
756 }
757
758 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, const IntSize& cur Size, int maxTextureSize)
759 {
760 IntSize adjustedSize = desiredSize;
761
762 // Clamp if the desired size is greater than the maximum texture size for th e device.
763 if (adjustedSize.height() > maxTextureSize)
764 adjustedSize.setHeight(maxTextureSize);
765
766 if (adjustedSize.width() > maxTextureSize)
767 adjustedSize.setWidth(maxTextureSize);
768
769 // Try progressively smaller sizes until we find a size that fits or reach a scale limit.
770 int scaleAttempts = 0;
771 while ((s_currentResourceUsePixels + pixelDelta(adjustedSize, curSize)) > s_ maximumResourceUsePixels) {
772 scaleAttempts++;
773 if (scaleAttempts > s_maxScaleAttempts)
774 return IntSize();
775
776 adjustedSize.scale(s_resourceAdjustedRatio);
777
778 if (adjustedSize.isEmpty())
779 return IntSize();
780 }
781
782 return adjustedSize;
783 }
784
785 IntSize DrawingBuffer::adjustSizeWithContextEviction(const IntSize& size, bool& evictContext)
786 {
787 IntSize adjustedSize = adjustSize(size, m_size, m_maxTextureSize);
788 if (!adjustedSize.isEmpty()) {
789 evictContext = false;
790 return adjustedSize; // Buffer fits without evicting a context.
791 }
792
793 // Speculatively adjust the pixel budget to see if the buffer would fit shou ld the oldest context be evicted.
794 IntSize oldestSize = m_contextEvictionManager->oldestContextSize();
795 int pixelDelta = oldestSize.width() * oldestSize.height();
796
797 s_currentResourceUsePixels -= pixelDelta;
798 adjustedSize = adjustSize(size, m_size, m_maxTextureSize);
799 s_currentResourceUsePixels += pixelDelta;
800
801 evictContext = !adjustedSize.isEmpty();
802 return adjustedSize;
803 }
804
805 bool DrawingBuffer::reset(const IntSize& newSize)
806 {
807 ASSERT(!newSize.isEmpty());
808 IntSize adjustedSize;
809 bool evictContext = false;
810 bool isNewContext = m_size.isEmpty();
811 if (s_allowContextEvictionOnCreate && isNewContext)
812 adjustedSize = adjustSizeWithContextEviction(newSize, evictContext);
813 else
814 adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize);
815
816 if (adjustedSize.isEmpty())
817 return false;
818
819 if (evictContext)
820 m_contextEvictionManager->forciblyLoseOldestContext("WARNING: WebGL cont exts have exceeded the maximum allowed backbuffer area. Oldest context will be l ost.");
821
822 if (adjustedSize != m_size) {
823 do {
824 // resize multisample FBO
825 if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffe r(adjustedSize)) {
826 adjustedSize.scale(s_resourceAdjustedRatio);
827 continue;
828 }
829 break;
830 } while (!adjustedSize.isEmpty());
831
832 setSize(adjustedSize);
833
834 if (adjustedSize.isEmpty())
835 return false;
836 }
837
838 m_context->disable(GL_SCISSOR_TEST);
839 m_context->clearColor(0, 0, 0, 0);
840 m_context->colorMask(true, true, true, true);
841
842 GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
843 if (m_actualAttributes.depth) {
844 m_context->clearDepth(1.0f);
845 clearMask |= GL_DEPTH_BUFFER_BIT;
846 m_context->depthMask(true);
847 }
848 if (m_actualAttributes.stencil) {
849 m_context->clearStencil(0);
850 clearMask |= GL_STENCIL_BUFFER_BIT;
851 m_context->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
852 }
853
854 clearFramebuffers(clearMask);
855 return true;
856 }
857
858 void DrawingBuffer::commit(long x, long y, long width, long height)
859 {
860 if (width < 0)
861 width = m_size.width();
862 if (height < 0)
863 height = m_size.height();
864
865 if (m_multisampleFBO && !m_contentsChangeCommitted) {
866 m_context->bindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO);
867 m_context->bindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo);
868
869 if (m_scissorEnabled)
870 m_context->disable(GL_SCISSOR_TEST);
871
872 // Use NEAREST, because there is no scale performed during the blit.
873 m_context->blitFramebufferCHROMIUM(x, y, width, height, x, y, width, hei ght, GL_COLOR_BUFFER_BIT, GL_NEAREST);
874
875 if (m_scissorEnabled)
876 m_context->enable(GL_SCISSOR_TEST);
877 }
878
879 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
880 m_contentsChangeCommitted = true;
881 }
882
883 void DrawingBuffer::restoreFramebufferBinding()
884 {
885 if (!m_framebufferBinding)
886 return;
887
888 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding);
889 }
890
891 bool DrawingBuffer::multisample() const
892 {
893 return m_multisampleMode != None;
894 }
895
896 void DrawingBuffer::bind()
897 {
898 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleF BO : m_fbo);
899 }
900
901 void DrawingBuffer::setPackAlignment(GLint param)
902 {
903 m_packAlignment = param;
904 }
905
906 void DrawingBuffer::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer)
907 {
908 paintFramebufferToCanvas(framebuffer(), size().width(), size().height(), !m_ actualAttributes.premultipliedAlpha, imageBuffer);
909 }
910
911 PassRefPtr<Uint8ClampedArray> DrawingBuffer::paintRenderingResultsToImageData(in t& width, int& height)
912 {
913 if (m_actualAttributes.premultipliedAlpha)
914 return nullptr;
915
916 width = size().width();
917 height = size().height();
918
919 Checked<int, RecordOverflow> dataSize = 4;
920 dataSize *= width;
921 dataSize *= height;
922 if (dataSize.hasOverflowed())
923 return nullptr;
924
925 RefPtr<Uint8ClampedArray> pixels = Uint8ClampedArray::createUninitialized(wi dth * height * 4);
926
927 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer());
928 readBackFramebuffer(pixels->data(), width, height, ReadbackRGBA, WebGLImageC onversion::AlphaDoNothing);
929 flipVertically(pixels->data(), width, height);
930
931 return pixels.release();
932 }
933
934 void DrawingBuffer::paintFramebufferToCanvas(int framebuffer, int width, int hei ght, bool premultiplyAlpha, ImageBuffer* imageBuffer)
935 {
936 unsigned char* pixels = 0;
937
938 const SkBitmap& canvasBitmap = imageBuffer->bitmap();
939 const SkBitmap* readbackBitmap = 0;
940 ASSERT(canvasBitmap.colorType() == kN32_SkColorType);
941 if (canvasBitmap.width() == width && canvasBitmap.height() == height) {
942 // This is the fastest and most common case. We read back
943 // directly into the canvas's backing store.
944 readbackBitmap = &canvasBitmap;
945 m_resizingBitmap.reset();
946 } else {
947 // We need to allocate a temporary bitmap for reading back the
948 // pixel data. We will then use Skia to rescale this bitmap to
949 // the size of the canvas's backing store.
950 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he ight)
951 m_resizingBitmap.allocN32Pixels(width, height);
952 readbackBitmap = &m_resizingBitmap;
953 }
954
955 // Read back the frame buffer.
956 SkAutoLockPixels bitmapLock(*readbackBitmap);
957 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
958
959 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
960 readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ? WebGLImageConversion::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing) ;
961 flipVertically(pixels, width, height);
962
963 readbackBitmap->notifyPixelsChanged();
964 if (m_resizingBitmap.readyToDraw()) {
965 // We need to draw the resizing bitmap into the canvas's backing store.
966 SkCanvas canvas(canvasBitmap);
967 SkRect dst;
968 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap.w idth()), SkIntToScalar(canvasBitmap.height()));
969 canvas.drawBitmapRect(m_resizingBitmap, 0, dst);
970 }
971 }
972
973 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, int width, int he ight, ReadbackOrder readbackOrder, WebGLImageConversion::AlphaOp op)
974 {
975 if (m_packAlignment > 4)
976 m_context->pixelStorei(GL_PACK_ALIGNMENT, 1);
977 m_context->readPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
978 if (m_packAlignment > 4)
979 m_context->pixelStorei(GL_PACK_ALIGNMENT, m_packAlignment);
980
981 size_t bufferSize = 4 * width * height;
982
983 if (readbackOrder == ReadbackSkia) {
984 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT
985 // Swizzle red and blue channels to match SkBitmap's byte ordering.
986 // TODO(kbr): expose GL_BGRA as extension.
987 for (size_t i = 0; i < bufferSize; i += 4) {
988 std::swap(pixels[i], pixels[i + 2]);
989 }
990 #endif
991 }
992
993 if (op == WebGLImageConversion::AlphaDoPremultiply) {
994 for (size_t i = 0; i < bufferSize; i += 4) {
995 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
996 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
997 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
998 }
999 } else if (op != WebGLImageConversion::AlphaDoNothing) {
1000 ASSERT_NOT_REACHED();
1001 }
1002 }
1003
1004 void DrawingBuffer::flipVertically(uint8_t* framebuffer, int width, int height)
1005 {
1006 m_scanline.resize(width * 4);
1007 uint8* scanline = &m_scanline[0];
1008 unsigned rowBytes = width * 4;
1009 unsigned count = height / 2;
1010 for (unsigned i = 0; i < count; i++) {
1011 uint8* rowA = framebuffer + i * rowBytes;
1012 uint8* rowB = framebuffer + (height - i - 1) * rowBytes;
1013 memcpy(scanline, rowB, rowBytes);
1014 memcpy(rowB, rowA, rowBytes);
1015 memcpy(rowA, scanline, rowBytes);
1016 }
1017 }
1018
1019 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment)
1020 {
1021 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);
1022 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0);
1023 }
1024
1025 void DrawingBuffer::allocateTextureMemory(TextureInfo* info, const IntSize& size )
1026 {
1027 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) {
1028 deleteChromiumImageForTexture(info);
1029
1030 info->imageId = m_context->createImageCHROMIUM(size.width(), size.height (), GL_RGBA8_OES, GC3D_IMAGE_SCANOUT_CHROMIUM);
1031 if (info->imageId) {
1032 m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId);
1033 return;
1034 }
1035 }
1036
1037 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE);
1038 }
1039
1040 void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info)
1041 {
1042 if (info->imageId) {
1043 m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId);
1044 m_context->destroyImageCHROMIUM(info->imageId);
1045 info->imageId = 0;
1046 }
1047 }
1048
1049 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/platform/graphics/gpu/DrawingBuffer.h ('k') | sky/engine/platform/graphics/gpu/DrawingBufferTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698