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

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

Issue 2261623002: Make DrawingBuffer and Canvas2DLayerBridge be cc::TextureLayerClients. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: webmailbox: add-todo-about-extra-mailboxing Created 4 years, 4 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
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 12 matching lines...) Expand all
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "platform/graphics/gpu/DrawingBuffer.h" 31 #include "platform/graphics/gpu/DrawingBuffer.h"
32 32
33 #include "cc/resources/shared_bitmap.h"
33 #include "gpu/GLES2/gl2extchromium.h" 34 #include "gpu/GLES2/gl2extchromium.h"
34 #include "gpu/command_buffer/client/gles2_interface.h" 35 #include "gpu/command_buffer/client/gles2_interface.h"
35 #include "gpu/command_buffer/common/capabilities.h" 36 #include "gpu/command_buffer/common/capabilities.h"
36 #include "platform/RuntimeEnabledFeatures.h" 37 #include "platform/RuntimeEnabledFeatures.h"
37 #include "platform/TraceEvent.h" 38 #include "platform/TraceEvent.h"
39 #include "platform/graphics/AcceleratedStaticBitmapImage.h"
38 #include "platform/graphics/GraphicsLayer.h" 40 #include "platform/graphics/GraphicsLayer.h"
39 #include "platform/graphics/ImageBuffer.h" 41 #include "platform/graphics/ImageBuffer.h"
40 #include "platform/graphics/gpu/Extensions3DUtil.h" 42 #include "platform/graphics/gpu/Extensions3DUtil.h"
41 #include "public/platform/Platform.h" 43 #include "public/platform/Platform.h"
42 #include "public/platform/WebCompositorSupport.h" 44 #include "public/platform/WebCompositorSupport.h"
43 #include "public/platform/WebExternalBitmap.h" 45 #include "public/platform/WebExternalBitmap.h"
44 #include "public/platform/WebExternalTextureLayer.h" 46 #include "public/platform/WebExternalTextureLayer.h"
45 #include "public/platform/WebGraphicsContext3DProvider.h" 47 #include "public/platform/WebGraphicsContext3DProvider.h"
48 #include "skia/ext/texture_handle.h"
49 #include "third_party/skia/include/gpu/GrContext.h"
50 #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
46 #include "wtf/CheckedNumeric.h" 51 #include "wtf/CheckedNumeric.h"
47 #include "wtf/PtrUtil.h" 52 #include "wtf/PtrUtil.h"
48 #include "wtf/typed_arrays/ArrayBufferContents.h" 53 #include "wtf/typed_arrays/ArrayBufferContents.h"
49 #include <algorithm> 54 #include <algorithm>
50 #include <memory> 55 #include <memory>
51 56
52 namespace blink { 57 namespace blink {
53 58
54 namespace { 59 namespace {
55 60
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 return !m_wantAlphaChannel && getMultisampledRenderbufferFormat() == GL_ RGBA8_OES; 230 return !m_wantAlphaChannel && getMultisampledRenderbufferFormat() == GL_ RGBA8_OES;
226 } 231 }
227 232
228 bool rgbEmulation = contextProvider()->getCapabilities().emulate_rgb_buffer_ with_rgba 233 bool rgbEmulation = contextProvider()->getCapabilities().emulate_rgb_buffer_ with_rgba
229 || (RuntimeEnabledFeatures::webGLImageChromiumEnabled() && contextProvid er()->getCapabilities().chromium_image_rgb_emulation); 234 || (RuntimeEnabledFeatures::webGLImageChromiumEnabled() && contextProvid er()->getCapabilities().chromium_image_rgb_emulation);
230 return !m_wantAlphaChannel && rgbEmulation; 235 return !m_wantAlphaChannel && rgbEmulation;
231 } 236 }
232 237
233 void DrawingBuffer::freeRecycledMailboxes() 238 void DrawingBuffer::freeRecycledMailboxes()
234 { 239 {
235 if (m_recycledMailboxQueue.isEmpty()) 240 while (!m_recycledMailboxQueue.isEmpty()) {
236 return; 241 RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast();
237 while (!m_recycledMailboxQueue.isEmpty()) 242 deleteMailbox(recycled->mailbox, recycled->syncToken);
238 deleteMailbox(m_recycledMailboxQueue.takeLast()); 243 }
239 } 244 }
240 245
241 bool DrawingBuffer::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExt ernalBitmap* bitmap) 246 std::unique_ptr<cc::SharedBitmap> DrawingBuffer::createOrRecycleBitmap()
247 {
248 for (auto it = m_recycledBitmapQueue.begin(); it != m_recycledBitmapQueue.en d(); ++it) {
249 if (it->size != m_size) {
250 m_recycledBitmapQueue.remove(it);
251 --it; // Removed this position so iterate on it again.
Ken Russell (switch to Gerrit) 2016/08/20 03:54:01 This won't assert if it was the first element that
danakj 2016/08/22 18:45:25 The DequeTest I added deletes element 0 and passes
252 }
253 }
254 if (!m_recycledBitmapQueue.isEmpty()) {
255 RecycledBitmap recycled = m_recycledBitmapQueue.takeLast();
256 DCHECK(recycled.size == m_size);
257 return std::move(recycled.bitmap);
258 }
259
260 return Platform::current()->allocateSharedBitmap(m_size);
261 }
262
263 bool DrawingBuffer::PrepareTextureMailbox(cc::TextureMailbox* outMailbox,
264 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback,
265 bool useSharedMemory)
242 { 266 {
243 if (m_destructionInProgress) { 267 if (m_destructionInProgress) {
244 // It can be hit in the following sequence. 268 // It can be hit in the following sequence.
245 // 1. WebGL draws something. 269 // 1. WebGL draws something.
246 // 2. The compositor begins the frame. 270 // 2. The compositor begins the frame.
247 // 3. Javascript makes a context lost using WEBGL_lose_context extension . 271 // 3. Javascript makes a context lost using WEBGL_lose_context extension .
248 // 4. Here. 272 // 4. Here.
249 return false; 273 return false;
250 } 274 }
251 ASSERT(!m_isHidden); 275 ASSERT(!m_isHidden);
252 if (!m_contentsChanged) 276 if (!m_contentsChanged)
253 return false; 277 return false;
254 278
255 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); 279 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox");
256 280
257 if (m_newMailboxCallback) 281 if (m_newMailboxCallback)
258 (*m_newMailboxCallback)(); 282 (*m_newMailboxCallback)();
259 283
260 // Resolve the multisampled buffer into m_colorBuffer texture. 284 // Resolve the multisampled buffer into m_colorBuffer texture.
261 if (m_antiAliasingMode != None) 285 if (m_antiAliasingMode != None)
262 commit(); 286 commit();
263 287
264 if (bitmap) { 288 if (useSharedMemory) {
265 bitmap->setSize(size()); 289 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap();
266 290 if (!bitmap)
291 return false;
267 unsigned char* pixels = bitmap->pixels(); 292 unsigned char* pixels = bitmap->pixels();
268 if (!pixels) 293 DCHECK(pixels);
269 return false;
270 294
271 bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha; 295 bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha;
272 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing; 296 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing;
273 readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSki a, op); 297 readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSki a, op);
298
299 *outMailbox = cc::TextureMailbox(bitmap.get(), m_size);
300
301 // This holds a ref on the DrawingBuffer that will keep it alive until t he
302 // mailbox is released (and while the release callback is running). It a lso
303 // owns the SharedBitmap.
304 auto func = WTF::bind(&DrawingBuffer::softwareMailboxReleased,
305 RefPtr<DrawingBuffer>(this),
306 WTF::passed(std::move(bitmap)),
307 m_size);
308 *outReleaseCallback = cc::SingleReleaseCallback::Create(
309 convertToBaseCallback(std::move(func)));
310 return true;
274 } 311 }
275 312
276 // We must restore the texture binding since creating new textures, 313 // We must restore the texture binding since creating new textures,
277 // consuming and producing mailboxes changes it. 314 // consuming and producing mailboxes changes it.
278 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, m_text ure2DBinding); 315 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, m_text ure2DBinding);
279 316
280 // First try to recycle an old buffer. 317 // First try to recycle an old buffer.
281 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); 318 RefPtr<MailboxInfo> mailboxInfo = takeRecycledMailbox();
282 319
283 // No buffer available to recycle, create a new one. 320 // No buffer available to recycle, create a new one.
284 if (!frontColorBufferMailbox) 321 if (!mailboxInfo)
285 frontColorBufferMailbox = createNewMailbox(createTextureAndAllocateMemor y(m_size)); 322 mailboxInfo = createNewMailbox(createTextureAndAllocateMemory(m_size));
286 323
287 if (m_preserveDrawingBuffer == Discard) { 324 if (m_preserveDrawingBuffer == Discard) {
288 std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer); 325 std::swap(mailboxInfo->textureInfo, m_colorBuffer);
289 attachColorBufferToReadFramebuffer(); 326 attachColorBufferToReadFramebuffer();
290 327
291 if (m_discardFramebufferSupported) { 328 if (m_discardFramebufferSupported) {
292 // Explicitly discard framebuffer to save GPU memory bandwidth for t ile-based GPU arch. 329 // Explicitly discard framebuffer to save GPU memory bandwidth for t ile-based GPU arch.
293 const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTAC HMENT, GL_STENCIL_ATTACHMENT }; 330 const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTAC HMENT, GL_STENCIL_ATTACHMENT };
294 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 331 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
295 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); 332 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
296 } 333 }
297 } else { 334 } else {
298 m_gl->CopySubTextureCHROMIUM(m_colorBuffer.textureId, frontColorBufferMa ilbox->textureInfo.textureId, 335 m_gl->CopySubTextureCHROMIUM(m_colorBuffer.textureId, mailboxInfo->textu reInfo.textureId,
299 0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_ FALSE); 336 0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_ FALSE);
300 } 337 }
301 338
302 restoreFramebufferBindings(); 339 restoreFramebufferBindings();
303 m_contentsChanged = false; 340 m_contentsChanged = false;
304 341
305 m_gl->ProduceTextureDirectCHROMIUM(frontColorBufferMailbox->textureInfo.text ureId, frontColorBufferMailbox->textureInfo.parameters.target, frontColorBufferM ailbox->mailbox.name); 342 m_gl->ProduceTextureDirectCHROMIUM(mailboxInfo->textureInfo.textureId, mailb oxInfo->textureInfo.parameters.target, mailboxInfo->mailbox.name);
306 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); 343 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
307 #if OS(MACOSX) 344 #if OS(MACOSX)
308 m_gl->DescheduleUntilFinishedCHROMIUM(); 345 m_gl->DescheduleUntilFinishedCHROMIUM();
309 #endif 346 #endif
310 m_gl->Flush(); 347 m_gl->Flush();
311 m_gl->GenSyncTokenCHROMIUM(fenceSync, frontColorBufferMailbox->mailbox.syncT oken); 348 gpu::SyncToken syncToken;
312 frontColorBufferMailbox->mailbox.validSyncToken = true; 349 m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
313 frontColorBufferMailbox->mailbox.allowOverlay = frontColorBufferMailbox->tex tureInfo.imageId != 0; 350
314 frontColorBufferMailbox->mailbox.textureTarget = frontColorBufferMailbox->te xtureInfo.parameters.target; 351 bool isOverlayCandidate = mailboxInfo->textureInfo.imageId != 0;
315 frontColorBufferMailbox->mailbox.textureSize = WebSize(m_size.width(), m_siz e.height()); 352 bool secureOutputOnly = false;
353 *outMailbox = cc::TextureMailbox(
354 mailboxInfo->mailbox, syncToken,
355 mailboxInfo->textureInfo.parameters.target,
356 gfx::Size(m_size.width(), m_size.height()),
357 isOverlayCandidate,
358 secureOutputOnly);
359
360 // This holds a ref on the DrawingBuffer that will keep it alive until the
361 // mailbox is released (and while the release callback is running).
362 auto func = WTF::bind(&DrawingBuffer::gpuMailboxReleased,
363 RefPtr<DrawingBuffer>(this),
364 mailboxInfo->mailbox);
365 *outReleaseCallback = cc::SingleReleaseCallback::Create(
366 convertToBaseCallback(std::move(func)));
367
368 m_frontColorBuffer = { mailboxInfo->mailbox, syncToken, mailboxInfo->texture Info };
316 setBufferClearNeeded(true); 369 setBufferClearNeeded(true);
317
318 // set m_parentDrawingBuffer to make sure 'this' stays alive as long as it h as live mailboxes
319 ASSERT(!frontColorBufferMailbox->m_parentDrawingBuffer);
320 frontColorBufferMailbox->m_parentDrawingBuffer = this;
321 *outMailbox = frontColorBufferMailbox->mailbox;
322 m_frontColorBuffer = { frontColorBufferMailbox->textureInfo, frontColorBuffe rMailbox->mailbox };
323 return true; 370 return true;
324 } 371 }
325 372
326 void DrawingBuffer::mailboxReleased(const WebExternalTextureMailbox& mailbox, bo ol lostResource) 373 void DrawingBuffer::gpuMailboxReleased(const gpu::Mailbox& mailbox, const gpu::S yncToken& syncToken,
374 bool lostResource)
327 { 375 {
328 if (m_destructionInProgress || m_gl->GetGraphicsResetStatusKHR() != GL_NO_ER ROR || lostResource || m_isHidden) { 376 if (m_destructionInProgress || m_gl->GetGraphicsResetStatusKHR() != GL_NO_ER ROR || lostResource || m_isHidden) {
329 mailboxReleasedWithoutRecycling(mailbox); 377 deleteMailbox(mailbox, syncToken);
330 return; 378 return;
331 } 379 }
332 380
333 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 381 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
334 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; 382 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i];
335 if (nameEquals(mailboxInfo->mailbox, mailbox)) { 383 if (mailboxInfo->mailbox == mailbox) {
336 memcpy(mailboxInfo->mailbox.syncToken, mailbox.syncToken, 384 m_recycledMailboxQueue.prepend(adoptRef(new RecycledMailbox(mailbox, syncToken)));
337 sizeof(mailboxInfo->mailbox.syncToken));
338 mailboxInfo->mailbox.validSyncToken = mailbox.validSyncToken;
339 ASSERT(mailboxInfo->m_parentDrawingBuffer.get() == this);
340 mailboxInfo->m_parentDrawingBuffer.clear();
341 m_recycledMailboxQueue.prepend(mailboxInfo->mailbox);
342 return; 385 return;
343 } 386 }
344 } 387 }
345 ASSERT_NOT_REACHED(); 388 ASSERT_NOT_REACHED();
346 } 389 }
347 390
391 void DrawingBuffer::softwareMailboxReleased(std::unique_ptr<cc::SharedBitmap> bi tmap, const IntSize& size, const gpu::SyncToken& syncToken, bool lostResource)
392 {
393 DCHECK(!syncToken.HasData()); // No sync tokens for software resources.
394 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size)
395 return; // Just delete the bitmap.
396
397 RecycledBitmap recycled = { std::move(bitmap), m_size };
398 m_recycledBitmapQueue.append(std::move(recycled));
399 }
400
401 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage()
402 {
403 // This can be null if the context is lost before the first call to grContex t().
404 GrContext* grContext = m_contextProvider->grContext();
405
406 cc::TextureMailbox textureMailbox;
407 std::unique_ptr<cc::SingleReleaseCallback> releaseCallback;
408 bool useSharedMemory = false;
409 bool success = false;
410 if (grContext)
411 success = PrepareTextureMailbox(&textureMailbox, &releaseCallback, useSh aredMemory);
412 if (!success) {
413 // If we can't get a mailbox, return an transparent black ImageBitmap.
414 // The only situation this could happen is when two or more calls to tra nsferToImageBitmap are made back-to-back, or when the context gets lost.
Ken Russell (switch to Gerrit) 2016/08/20 03:54:01 The intent of transferToStaticBitmapImage is that
danakj 2016/08/22 18:45:24 So I think how this works is if |m_preserveDrawing
Ken Russell (switch to Gerrit) 2016/08/22 19:03:11 Thanks for this explanation - sounds good.
415 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(m_size.width() , m_size.height());
416 return StaticBitmapImage::create(fromSkSp(surface->makeImageSnapshot())) ;
417 }
418
419 DCHECK_EQ(m_size.width(), textureMailbox.size_in_pixels().width());
420 DCHECK_EQ(m_size.height(), textureMailbox.size_in_pixels().height());
421
422 // Make our own textureId that is a reference on the same texture backing be ing used as the front
423 // buffer (which was returned from PrepareTextureMailbox()).
424 // TODO(danakj): Instead of using PrepareTextureMailbox(), we could just use the actual texture id and
425 // avoid this whole dance of wait for sync token, consume, generate new sync token.
Ken Russell (switch to Gerrit) 2016/08/20 03:54:01 It's possible this wasn't implemented as desired b
danakj 2016/08/22 19:01:04 I think this is what is happening. We PrepareTextu
Ken Russell (switch to Gerrit) 2016/08/22 19:03:11 I see. Thanks for this explanation. Per our offlin
426 m_gl->WaitSyncTokenCHROMIUM(textureMailbox.GetSyncTokenData());
427 GLuint textureId = m_gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, text ureMailbox.name());
428 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
429 m_gl->Flush();
430 gpu::SyncToken syncToken;
431 m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
432 // Return the mailbox but report that the resource is lost to prevent trying to use
433 // the backing for future frames. We keep it alive with our own reference to the
434 // backing via our |textureId|.
435 releaseCallback->Run(syncToken, true /* lostResource */);
436
437 // Store that texture id as the backing for an SkImage.
438 GrGLTextureInfo textureInfo;
439 textureInfo.fTarget = GL_TEXTURE_2D;
440 textureInfo.fID = textureId;
441 GrBackendTextureDesc backendTexture;
442 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
443 backendTexture.fWidth = m_size.width();
444 backendTexture.fHeight = m_size.height();
445 backendTexture.fConfig = kSkia8888_GrPixelConfig;
446 backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textu reInfo);
447 sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendT exture);
448
449 // Hold a ref on the GrContext for the texture backing the |skImage|.
450 sk_sp<GrContext> grContextRef = sk_ref_sp(grContext);
451 // We reuse the same mailbox name from above since our texture id was consum ed from it.
452 const auto& skImageMailbox = textureMailbox.mailbox();
453 // Use the sync token generated after producing the mailbox. Waiting for thi s before trying to use
454 // the mailbox with some other context will ensure it is valid. We wouldn't need to wait for the
455 // consume because the texture id it generated would only be valid for the D rawingBuffer's context
456 // anyways.
457 const auto& skImageSyncToken = textureMailbox.sync_token();
458
459 // TODO(xidachen): Create a small pool of recycled textures from ImageBitmap RenderingContext's
460 // transferFromImageBitmap, and try to use them in DrawingBuffer.
461 return AcceleratedStaticBitmapImage::create(fromSkSp(skImage), grContextRef, skImageMailbox, skImageSyncToken);
462 }
463
348 DrawingBuffer::TextureParameters DrawingBuffer::chromiumImageTextureParameters() 464 DrawingBuffer::TextureParameters DrawingBuffer::chromiumImageTextureParameters()
349 { 465 {
350 #if OS(MACOSX) 466 #if OS(MACOSX)
351 // A CHROMIUM_image backed texture requires a specialized set of parameters 467 // A CHROMIUM_image backed texture requires a specialized set of parameters
352 // on OSX. 468 // on OSX.
353 TextureParameters parameters; 469 TextureParameters parameters;
354 parameters.target = GC3D_TEXTURE_RECTANGLE_ARB; 470 parameters.target = GC3D_TEXTURE_RECTANGLE_ARB;
355 471
356 if (m_wantAlphaChannel) { 472 if (m_wantAlphaChannel) {
357 parameters.creationInternalColorFormat = GL_RGBA; 473 parameters.creationInternalColorFormat = GL_RGBA;
(...skipping 29 matching lines...) Expand all
387 parameters.colorFormat = GL_RGBA; 503 parameters.colorFormat = GL_RGBA;
388 } else { 504 } else {
389 GLenum format = defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RG BA : GL_RGB; 505 GLenum format = defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RG BA : GL_RGB;
390 parameters.creationInternalColorFormat = format; 506 parameters.creationInternalColorFormat = format;
391 parameters.internalColorFormat = format; 507 parameters.internalColorFormat = format;
392 parameters.colorFormat = format; 508 parameters.colorFormat = format;
393 } 509 }
394 return parameters; 510 return parameters;
395 } 511 }
396 512
397 void DrawingBuffer::mailboxReleasedWithoutRecycling(const WebExternalTextureMail box& mailbox) 513 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::takeRecycledMailbox()
398 {
399 ASSERT(m_textureMailboxes.size());
400 // Ensure not to call the destructor until deleteMailbox() is completed.
401 RefPtr<DrawingBuffer> self = this;
402 deleteMailbox(mailbox);
403 }
404
405 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
406 { 514 {
407 if (m_recycledMailboxQueue.isEmpty()) 515 if (m_recycledMailboxQueue.isEmpty())
408 return PassRefPtr<MailboxInfo>(); 516 return nullptr;
409 517
410 // Creation of image backed mailboxes is very expensive, so be less 518 // Creation of image backed mailboxes is very expensive, so be less
411 // aggressive about pruning them. 519 // aggressive about pruning them.
412 size_t cacheLimit = 1; 520 size_t cacheLimit = 1;
413 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) 521 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled())
414 cacheLimit = 4; 522 cacheLimit = 4;
415 523
416 WebExternalTextureMailbox mailbox; 524 RefPtr<RecycledMailbox> recycled;
417 while (m_recycledMailboxQueue.size() > cacheLimit) { 525 while (m_recycledMailboxQueue.size() > cacheLimit) {
418 mailbox = m_recycledMailboxQueue.takeLast(); 526 recycled = m_recycledMailboxQueue.takeLast();
419 deleteMailbox(mailbox); 527 deleteMailbox(recycled->mailbox, recycled->syncToken);
420 } 528 }
421 mailbox = m_recycledMailboxQueue.takeLast(); 529 recycled = m_recycledMailboxQueue.takeLast();
530
531 if (recycled->syncToken.HasData())
532 m_gl->WaitSyncTokenCHROMIUM(recycled->syncToken.GetData());
422 533
423 RefPtr<MailboxInfo> mailboxInfo; 534 RefPtr<MailboxInfo> mailboxInfo;
424 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 535 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
425 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { 536 if (m_textureMailboxes[i]->mailbox == recycled->mailbox) {
426 mailboxInfo = m_textureMailboxes[i]; 537 mailboxInfo = m_textureMailboxes[i];
427 break; 538 break;
428 } 539 }
429 } 540 }
430 ASSERT(mailboxInfo); 541 ASSERT(mailboxInfo);
431 542
432 if (mailboxInfo->mailbox.validSyncToken) {
433 m_gl->WaitSyncTokenCHROMIUM(mailboxInfo->mailbox.syncToken);
434 mailboxInfo->mailbox.validSyncToken = false;
435 }
436
437 if (mailboxInfo->size != m_size) { 543 if (mailboxInfo->size != m_size) {
438 resizeTextureMemory(&mailboxInfo->textureInfo, m_size); 544 resizeTextureMemory(&mailboxInfo->textureInfo, m_size);
439 mailboxInfo->size = m_size; 545 mailboxInfo->size = m_size;
440 } 546 }
441 547
442 return mailboxInfo.release(); 548 return mailboxInfo.release();
443 } 549 }
444 550
445 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const Tex tureInfo& info) 551 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const Tex tureInfo& info)
446 { 552 {
447 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); 553 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo);
448 m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name); 554 m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name);
449 returnMailbox->textureInfo = info; 555 returnMailbox->textureInfo = info;
450 returnMailbox->size = m_size; 556 returnMailbox->size = m_size;
451 m_textureMailboxes.append(returnMailbox); 557 m_textureMailboxes.append(returnMailbox);
452 return returnMailbox.release(); 558 return returnMailbox.release();
453 } 559 }
454 560
455 void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox) 561 void DrawingBuffer::deleteMailbox(const gpu::Mailbox& mailbox, const gpu::SyncTo ken& syncToken)
456 { 562 {
563 if (syncToken.HasData())
564 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetConstData());
457 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 565 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
458 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { 566 if (m_textureMailboxes[i]->mailbox == mailbox) {
459 if (mailbox.validSyncToken)
460 m_gl->WaitSyncTokenCHROMIUM(mailbox.syncToken);
461
462 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); 567 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo);
463
464 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI d); 568 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI d);
465 m_textureMailboxes.remove(i); 569 m_textureMailboxes.remove(i);
466 return; 570 return;
467 } 571 }
468 } 572 }
469 ASSERT_NOT_REACHED(); 573 ASSERT_NOT_REACHED();
470 } 574 }
471 575
472 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) 576 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling)
473 { 577 {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 restoreFramebufferBindings(); 634 restoreFramebufferBindings();
531 } 635 }
532 m_gl->Flush(); 636 m_gl->Flush();
533 } 637 }
534 638
535 // Assume that the destination target is GL_TEXTURE_2D. 639 // Assume that the destination target is GL_TEXTURE_2D.
536 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalForm at, destType, level)) 640 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalForm at, destType, level))
537 return false; 641 return false;
538 642
539 // Contexts may be in a different share group. We must transfer the texture through a mailbox first 643 // Contexts may be in a different share group. We must transfer the texture through a mailbox first
540 WebExternalTextureMailbox mailbox;
541 GLint textureId = 0; 644 GLint textureId = 0;
542 GLenum target = 0; 645 GLenum target = 0;
646 gpu::Mailbox mailbox;
647 gpu::SyncToken produceSyncToken;
543 if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) { 648 if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
544 textureId = m_frontColorBuffer.texInfo.textureId; 649 textureId = m_frontColorBuffer.texInfo.textureId;
650 target = m_frontColorBuffer.texInfo.parameters.target;
545 mailbox = m_frontColorBuffer.mailbox; 651 mailbox = m_frontColorBuffer.mailbox;
546 target = m_frontColorBuffer.texInfo.parameters.target; 652 produceSyncToken = m_frontColorBuffer.produceSyncToken;
547 } else { 653 } else {
548 textureId = m_colorBuffer.textureId; 654 textureId = m_colorBuffer.textureId;
549 target = m_colorBuffer.parameters.target; 655 target = m_colorBuffer.parameters.target;
550 m_gl->GenMailboxCHROMIUM(mailbox.name); 656 m_gl->GenMailboxCHROMIUM(mailbox.name);
551 m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name); 657 m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name);
552 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); 658 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
553 m_gl->Flush(); 659 m_gl->Flush();
554 m_gl->GenSyncTokenCHROMIUM(fenceSync, mailbox.syncToken); 660 m_gl->GenSyncTokenCHROMIUM(fenceSync, produceSyncToken.GetData());
555 mailbox.validSyncToken = true;
556 } 661 }
557 662
558 if (mailbox.validSyncToken) 663 DCHECK(produceSyncToken.HasData());
559 gl->WaitSyncTokenCHROMIUM(mailbox.syncToken); 664 gl->WaitSyncTokenCHROMIUM(produceSyncToken.GetConstData());
560 GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.n ame); 665 GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.n ame);
561 666
562 GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE; 667 GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE;
563 GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE; 668 GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE;
564 if (m_wantAlphaChannel && m_premultipliedAlpha && !premultiplyAlpha) 669 if (m_wantAlphaChannel && m_premultipliedAlpha && !premultiplyAlpha)
565 unpackUnpremultiplyAlphaNeeded = GL_TRUE; 670 unpackUnpremultiplyAlphaNeeded = GL_TRUE;
566 else if (m_wantAlphaChannel && !m_premultipliedAlpha && premultiplyAlpha) 671 else if (m_wantAlphaChannel && !m_premultipliedAlpha && premultiplyAlpha)
567 unpackPremultiplyAlphaNeeded = GL_TRUE; 672 unpackPremultiplyAlphaNeeded = GL_TRUE;
568 673
569 gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, fl ipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded); 674 gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, fl ipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded);
570 675
571 gl->DeleteTextures(1, &sourceTexture); 676 gl->DeleteTextures(1, &sourceTexture);
572 677
573 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); 678 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
574 679
575 gl->Flush(); 680 gl->Flush();
576 GLbyte syncToken[GL_SYNC_TOKEN_SIZE_CHROMIUM] = { 0 }; 681 gpu::SyncToken syncToken;
577 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken); 682 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
578 m_gl->WaitSyncTokenCHROMIUM(syncToken); 683 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData());
579 684
580 return true; 685 return true;
581 } 686 }
582 687
583 GLuint DrawingBuffer::framebuffer() const 688 GLuint DrawingBuffer::framebuffer() const
584 { 689 {
585 return m_fbo; 690 return m_fbo;
586 } 691 }
587 692
588 WebLayer* DrawingBuffer::platformLayer() 693 WebLayer* DrawingBuffer::platformLayer()
(...skipping 18 matching lines...) Expand all
607 712
608 m_gl->Flush(); 713 m_gl->Flush();
609 } 714 }
610 715
611 void DrawingBuffer::beginDestruction() 716 void DrawingBuffer::beginDestruction()
612 { 717 {
613 ASSERT(!m_destructionInProgress); 718 ASSERT(!m_destructionInProgress);
614 m_destructionInProgress = true; 719 m_destructionInProgress = true;
615 720
616 clearPlatformLayer(); 721 clearPlatformLayer();
617 722 freeRecycledMailboxes();
618 while (!m_recycledMailboxQueue.isEmpty())
619 deleteMailbox(m_recycledMailboxQueue.takeLast());
620 723
621 if (m_multisampleFBO) 724 if (m_multisampleFBO)
622 m_gl->DeleteFramebuffers(1, &m_multisampleFBO); 725 m_gl->DeleteFramebuffers(1, &m_multisampleFBO);
623 726
624 if (m_fbo) 727 if (m_fbo)
625 m_gl->DeleteFramebuffers(1, &m_fbo); 728 m_gl->DeleteFramebuffers(1, &m_fbo);
626 729
627 if (m_multisampleRenderbuffer) 730 if (m_multisampleRenderbuffer)
628 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); 731 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);
629 732
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 1215
1113 void DrawingBuffer::restoreTextureBindings() 1216 void DrawingBuffer::restoreTextureBindings()
1114 { 1217 {
1115 // This class potentially modifies the bindings for GL_TEXTURE_2D and 1218 // This class potentially modifies the bindings for GL_TEXTURE_2D and
1116 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since 1219 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since
1117 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. 1220 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE.
1118 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); 1221 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding);
1119 } 1222 }
1120 1223
1121 } // namespace blink 1224 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698