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

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: oopsnamespace 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.
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.
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()).
piman 2016/08/19 22:30:21 Why do we do this dance? The texture was created o
danakj 2016/08/19 22:37:17 Since this function is acting on a mailbox only it
danakj 2016/08/19 22:43:03 Oh or are you saying I could do the consume but no
piman 2016/08/19 23:11:35 It's super subtle, but this works I guess - provid
424 m_gl->WaitSyncTokenCHROMIUM(textureMailbox.GetSyncTokenData());
425 GLuint textureId = m_gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, text ureMailbox.name());
426 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
427 m_gl->Flush();
428 gpu::SyncToken syncToken;
429 m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
430 // Return the mailbox but report that the resource is lost to prevent trying to use
431 // the backing for future frames. We keep it alive with our own reference to the
432 // backing via our |textureId|.
433 releaseCallback->Run(syncToken, true /* lostResource */);
434
435 // Store that texture id as the backing for an SkImage.
436 GrGLTextureInfo textureInfo;
437 textureInfo.fTarget = GL_TEXTURE_2D;
438 textureInfo.fID = textureId;
439 GrBackendTextureDesc backendTexture;
440 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
441 backendTexture.fWidth = m_size.width();
442 backendTexture.fHeight = m_size.height();
443 backendTexture.fConfig = kSkia8888_GrPixelConfig;
444 backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textu reInfo);
445 sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendT exture);
446
447 // Hold a ref on the GrContext for the texture backing the |skImage|.
448 sk_sp<GrContext> grContextRef = sk_ref_sp(grContext);
449 // We reuse the same mailbox name from above since our texture id was consum ed from it.
450 const auto& skImageMailbox = textureMailbox.mailbox();
451 // Use the sync token generated after producing the mailbox. Waiting for thi s before trying to use
452 // the mailbox with some other context will ensure it is valid. We wouldn't need to wait for the
453 // consume because the texture id it generated would only be valid for the D rawingBuffer's context
454 // anyways.
455 const auto& skImageSyncToken = textureMailbox.sync_token();
456
457 // TODO(xidachen): Create a small pool of recycled textures from ImageBitmap RenderingContext's
458 // transferFromImageBitmap, and try to use them in DrawingBuffer.
459 return AcceleratedStaticBitmapImage::create(fromSkSp(skImage), fromSkSp(grCo ntextRef), skImageMailbox, skImageSyncToken);
460 }
461
348 DrawingBuffer::TextureParameters DrawingBuffer::chromiumImageTextureParameters() 462 DrawingBuffer::TextureParameters DrawingBuffer::chromiumImageTextureParameters()
349 { 463 {
350 #if OS(MACOSX) 464 #if OS(MACOSX)
351 // A CHROMIUM_image backed texture requires a specialized set of parameters 465 // A CHROMIUM_image backed texture requires a specialized set of parameters
352 // on OSX. 466 // on OSX.
353 TextureParameters parameters; 467 TextureParameters parameters;
354 parameters.target = GC3D_TEXTURE_RECTANGLE_ARB; 468 parameters.target = GC3D_TEXTURE_RECTANGLE_ARB;
355 469
356 if (m_wantAlphaChannel) { 470 if (m_wantAlphaChannel) {
357 parameters.creationInternalColorFormat = GL_RGBA; 471 parameters.creationInternalColorFormat = GL_RGBA;
(...skipping 29 matching lines...) Expand all
387 parameters.colorFormat = GL_RGBA; 501 parameters.colorFormat = GL_RGBA;
388 } else { 502 } else {
389 GLenum format = defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RG BA : GL_RGB; 503 GLenum format = defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RG BA : GL_RGB;
390 parameters.creationInternalColorFormat = format; 504 parameters.creationInternalColorFormat = format;
391 parameters.internalColorFormat = format; 505 parameters.internalColorFormat = format;
392 parameters.colorFormat = format; 506 parameters.colorFormat = format;
393 } 507 }
394 return parameters; 508 return parameters;
395 } 509 }
396 510
397 void DrawingBuffer::mailboxReleasedWithoutRecycling(const WebExternalTextureMail box& mailbox) 511 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 { 512 {
407 if (m_recycledMailboxQueue.isEmpty()) 513 if (m_recycledMailboxQueue.isEmpty())
408 return PassRefPtr<MailboxInfo>(); 514 return nullptr;
409 515
410 // Creation of image backed mailboxes is very expensive, so be less 516 // Creation of image backed mailboxes is very expensive, so be less
411 // aggressive about pruning them. 517 // aggressive about pruning them.
412 size_t cacheLimit = 1; 518 size_t cacheLimit = 1;
413 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) 519 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled())
414 cacheLimit = 4; 520 cacheLimit = 4;
415 521
416 WebExternalTextureMailbox mailbox; 522 RefPtr<RecycledMailbox> recycled;
417 while (m_recycledMailboxQueue.size() > cacheLimit) { 523 while (m_recycledMailboxQueue.size() > cacheLimit) {
418 mailbox = m_recycledMailboxQueue.takeLast(); 524 recycled = m_recycledMailboxQueue.takeLast();
419 deleteMailbox(mailbox); 525 deleteMailbox(recycled->mailbox, recycled->syncToken);
420 } 526 }
421 mailbox = m_recycledMailboxQueue.takeLast(); 527 recycled = m_recycledMailboxQueue.takeLast();
528
529 if (recycled->syncToken.HasData())
530 m_gl->WaitSyncTokenCHROMIUM(recycled->syncToken.GetData());
422 531
423 RefPtr<MailboxInfo> mailboxInfo; 532 RefPtr<MailboxInfo> mailboxInfo;
424 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 533 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
425 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { 534 if (m_textureMailboxes[i]->mailbox == recycled->mailbox) {
426 mailboxInfo = m_textureMailboxes[i]; 535 mailboxInfo = m_textureMailboxes[i];
427 break; 536 break;
428 } 537 }
429 } 538 }
430 ASSERT(mailboxInfo); 539 ASSERT(mailboxInfo);
431 540
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) { 541 if (mailboxInfo->size != m_size) {
438 resizeTextureMemory(&mailboxInfo->textureInfo, m_size); 542 resizeTextureMemory(&mailboxInfo->textureInfo, m_size);
439 mailboxInfo->size = m_size; 543 mailboxInfo->size = m_size;
440 } 544 }
441 545
442 return mailboxInfo.release(); 546 return mailboxInfo.release();
443 } 547 }
444 548
445 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const Tex tureInfo& info) 549 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const Tex tureInfo& info)
446 { 550 {
447 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); 551 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo);
448 m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name); 552 m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name);
449 returnMailbox->textureInfo = info; 553 returnMailbox->textureInfo = info;
450 returnMailbox->size = m_size; 554 returnMailbox->size = m_size;
451 m_textureMailboxes.append(returnMailbox); 555 m_textureMailboxes.append(returnMailbox);
452 return returnMailbox.release(); 556 return returnMailbox.release();
453 } 557 }
454 558
455 void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox) 559 void DrawingBuffer::deleteMailbox(const gpu::Mailbox& mailbox, const gpu::SyncTo ken& syncToken)
456 { 560 {
561 if (syncToken.HasData())
562 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetConstData());
457 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 563 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
458 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { 564 if (m_textureMailboxes[i]->mailbox == mailbox) {
459 if (mailbox.validSyncToken)
460 m_gl->WaitSyncTokenCHROMIUM(mailbox.syncToken);
461
462 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); 565 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo);
463
464 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI d); 566 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI d);
465 m_textureMailboxes.remove(i); 567 m_textureMailboxes.remove(i);
466 return; 568 return;
467 } 569 }
468 } 570 }
469 ASSERT_NOT_REACHED(); 571 ASSERT_NOT_REACHED();
470 } 572 }
471 573
472 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) 574 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling)
473 { 575 {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 restoreFramebufferBindings(); 632 restoreFramebufferBindings();
531 } 633 }
532 m_gl->Flush(); 634 m_gl->Flush();
533 } 635 }
534 636
535 // Assume that the destination target is GL_TEXTURE_2D. 637 // Assume that the destination target is GL_TEXTURE_2D.
536 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalForm at, destType, level)) 638 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalForm at, destType, level))
537 return false; 639 return false;
538 640
539 // Contexts may be in a different share group. We must transfer the texture through a mailbox first 641 // Contexts may be in a different share group. We must transfer the texture through a mailbox first
540 WebExternalTextureMailbox mailbox;
541 GLint textureId = 0; 642 GLint textureId = 0;
542 GLenum target = 0; 643 GLenum target = 0;
644 gpu::Mailbox mailbox;
645 gpu::SyncToken produceSyncToken;
543 if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) { 646 if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
544 textureId = m_frontColorBuffer.texInfo.textureId; 647 textureId = m_frontColorBuffer.texInfo.textureId;
648 target = m_frontColorBuffer.texInfo.parameters.target;
545 mailbox = m_frontColorBuffer.mailbox; 649 mailbox = m_frontColorBuffer.mailbox;
546 target = m_frontColorBuffer.texInfo.parameters.target; 650 produceSyncToken = m_frontColorBuffer.produceSyncToken;
547 } else { 651 } else {
548 textureId = m_colorBuffer.textureId; 652 textureId = m_colorBuffer.textureId;
549 target = m_colorBuffer.parameters.target; 653 target = m_colorBuffer.parameters.target;
550 m_gl->GenMailboxCHROMIUM(mailbox.name); 654 m_gl->GenMailboxCHROMIUM(mailbox.name);
551 m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name); 655 m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name);
552 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); 656 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
553 m_gl->Flush(); 657 m_gl->Flush();
554 m_gl->GenSyncTokenCHROMIUM(fenceSync, mailbox.syncToken); 658 m_gl->GenSyncTokenCHROMIUM(fenceSync, produceSyncToken.GetData());
555 mailbox.validSyncToken = true;
556 } 659 }
557 660
558 if (mailbox.validSyncToken) 661 DCHECK(produceSyncToken.HasData());
559 gl->WaitSyncTokenCHROMIUM(mailbox.syncToken); 662 gl->WaitSyncTokenCHROMIUM(produceSyncToken.GetConstData());
560 GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.n ame); 663 GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.n ame);
561 664
562 GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE; 665 GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE;
563 GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE; 666 GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE;
564 if (m_wantAlphaChannel && m_premultipliedAlpha && !premultiplyAlpha) 667 if (m_wantAlphaChannel && m_premultipliedAlpha && !premultiplyAlpha)
565 unpackUnpremultiplyAlphaNeeded = GL_TRUE; 668 unpackUnpremultiplyAlphaNeeded = GL_TRUE;
566 else if (m_wantAlphaChannel && !m_premultipliedAlpha && premultiplyAlpha) 669 else if (m_wantAlphaChannel && !m_premultipliedAlpha && premultiplyAlpha)
567 unpackPremultiplyAlphaNeeded = GL_TRUE; 670 unpackPremultiplyAlphaNeeded = GL_TRUE;
568 671
569 gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, fl ipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded); 672 gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, fl ipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded);
570 673
571 gl->DeleteTextures(1, &sourceTexture); 674 gl->DeleteTextures(1, &sourceTexture);
572 675
573 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); 676 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
574 677
575 gl->Flush(); 678 gl->Flush();
576 GLbyte syncToken[GL_SYNC_TOKEN_SIZE_CHROMIUM] = { 0 }; 679 gpu::SyncToken syncToken;
577 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken); 680 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
578 m_gl->WaitSyncTokenCHROMIUM(syncToken); 681 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData());
579 682
580 return true; 683 return true;
581 } 684 }
582 685
583 GLuint DrawingBuffer::framebuffer() const 686 GLuint DrawingBuffer::framebuffer() const
584 { 687 {
585 return m_fbo; 688 return m_fbo;
586 } 689 }
587 690
588 WebLayer* DrawingBuffer::platformLayer() 691 WebLayer* DrawingBuffer::platformLayer()
(...skipping 18 matching lines...) Expand all
607 710
608 m_gl->Flush(); 711 m_gl->Flush();
609 } 712 }
610 713
611 void DrawingBuffer::beginDestruction() 714 void DrawingBuffer::beginDestruction()
612 { 715 {
613 ASSERT(!m_destructionInProgress); 716 ASSERT(!m_destructionInProgress);
614 m_destructionInProgress = true; 717 m_destructionInProgress = true;
615 718
616 clearPlatformLayer(); 719 clearPlatformLayer();
617 720 freeRecycledMailboxes();
618 while (!m_recycledMailboxQueue.isEmpty())
619 deleteMailbox(m_recycledMailboxQueue.takeLast());
620 721
621 if (m_multisampleFBO) 722 if (m_multisampleFBO)
622 m_gl->DeleteFramebuffers(1, &m_multisampleFBO); 723 m_gl->DeleteFramebuffers(1, &m_multisampleFBO);
623 724
624 if (m_fbo) 725 if (m_fbo)
625 m_gl->DeleteFramebuffers(1, &m_fbo); 726 m_gl->DeleteFramebuffers(1, &m_fbo);
626 727
627 if (m_multisampleRenderbuffer) 728 if (m_multisampleRenderbuffer)
628 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); 729 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);
629 730
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 1213
1113 void DrawingBuffer::restoreTextureBindings() 1214 void DrawingBuffer::restoreTextureBindings()
1114 { 1215 {
1115 // This class potentially modifies the bindings for GL_TEXTURE_2D and 1216 // This class potentially modifies the bindings for GL_TEXTURE_2D and
1116 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since 1217 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since
1117 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. 1218 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE.
1118 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); 1219 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding);
1119 } 1220 }
1120 1221
1121 } // namespace blink 1222 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698