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

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

Issue 1757033002: CL for perf tryjob on mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 return true; 189 return true;
190 if (m_surface) // && !m_layer is implied 190 if (m_surface) // && !m_layer is implied
191 return false; 191 return false;
192 192
193 // Whether or not to accelerate is not yet resolved, determine whether immed iate presentation 193 // Whether or not to accelerate is not yet resolved, determine whether immed iate presentation
194 // of the canvas would result in the canvas being accelerated. Presentation is assumed to be 194 // of the canvas would result in the canvas being accelerated. Presentation is assumed to be
195 // a 'PreferAcceleration' operation. 195 // a 'PreferAcceleration' operation.
196 return shouldAccelerate(PreferAcceleration); 196 return shouldAccelerate(PreferAcceleration);
197 } 197 }
198 198
199 GLenum Canvas2DLayerBridge::getGLFilter()
200 {
201 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR;
202 }
203
204 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage(RefPtr<SkImage>& imag e, WebExternalTextureMailbox* outMailbox)
205 {
206 GLuint textureId, imageId;
207 if (!createIOSurfaceBackedTexture(&textureId, &imageId))
208 return false;
209
210 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu reHandle(true))->fID;
211 context()->copyTextureCHROMIUM(imageTexture, textureId, GL_BGRA_EXT, GL_UNSI GNED_BYTE, GL_FALSE, GL_FALSE, GL_FALSE);
212
213 MailboxInfo& info = createMailboxInfo();
214 info.m_mailbox.textureTarget = GC3D_TEXTURE_RECTANGLE_ARB;
215 context()->genMailboxCHROMIUM(info.m_mailbox.name);
216 context()->produceTextureDirectCHROMIUM(textureId, info.m_mailbox.textureTar get, info.m_mailbox.name);
217 info.m_mailbox.allowOverlay = true;
218 info.m_mailbox.nearestNeighbor = getGLFilter();
219
220 const WGC3Duint64 fenceSync = context()->insertFenceSyncCHROMIUM();
221 context()->flush();
222 info.m_mailbox.validSyncToken = context()->genSyncTokenCHROMIUM(fenceSync, i nfo.m_mailbox.syncToken);
223
224 info.m_CHROMIUMImageId = imageId;
225 info.m_textureId = textureId;
226 *outMailbox = info.m_mailbox;
227
228 // Because we are changing the texture binding without going through skia,
229 // we must dirty the context.
230 GrContext* grContext = m_contextProvider->grContext();
231 grContext->resetContext(kTextureBinding_GrGLBackendState);
232
233 return true;
234 }
235
236 bool Canvas2DLayerBridge::createIOSurfaceBackedTexture(GLuint* outTexture, GLuin t* outImageId)
237 {
238 WebGraphicsContext3D* webContext = context();
239 GLuint imageId = webContext->createGpuMemoryBufferImageCHROMIUM(m_size.width (), m_size.height(), GL_BGRA_EXT, GC3D_SCANOUT_CHROMIUM);
240 if (!imageId)
241 return false;
242
243 GLuint textureId= webContext->createTexture();
244 if (!textureId) {
245 webContext->destroyImageCHROMIUM(imageId);
246 return false;
247 }
248
249 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB;
250 webContext->bindTexture(target, textureId);
251 webContext->texParameteri(target, GL_TEXTURE_MAG_FILTER, getGLFilter());
252 webContext->texParameteri(target, GL_TEXTURE_MIN_FILTER, getGLFilter());
253 webContext->texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
254 webContext->texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
255 webContext->bindTexImage2DCHROMIUM(target, imageId);
256
257 *outTexture = textureId;
258 *outImageId = imageId;
259 return true;
260 }
261
262 Canvas2DLayerBridge::MailboxInfo& Canvas2DLayerBridge::createMailboxInfo()
263 {
264 MailboxInfo tmp;
265 tmp.m_parentLayerBridge = this;
266 m_mailboxes.prepend(tmp);
267 MailboxInfo& mailboxInfo = m_mailboxes.first();
268 return mailboxInfo;
269 }
270
271 bool Canvas2DLayerBridge::prepareMailboxFromImage(RefPtr<SkImage>& image, WebExt ernalTextureMailbox* outMailbox)
272 {
273 GrContext* grContext = m_contextProvider->grContext();
274 if (RuntimeEnabledFeatures::canvas2dImageChromiumEnabled()) {
275 if (grContext && prepareIOSurfaceMailboxFromImage(image, outMailbox))
276 return true;
277 }
278
279 MailboxInfo& mailboxInfo = createMailboxInfo();
280 mailboxInfo.m_mailbox.nearestNeighbor = getGLFilter() == GL_NEAREST;
281 mailboxInfo.m_image = image;
282
283 if (!grContext)
284 return true; // for testing: skip gl stuff when using a mock graphics co ntext.
285
286 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled())
287 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode) ;
288
289 // Need to flush skia's internal queue because texture is about to be access ed directly
290 grContext->flush();
291
292 // Because of texture sharing with the compositor, we must invalidate
293 // the state cached in skia so that the deferred copy on write
294 // in SkSurface_Gpu does not make any false assumptions.
295 mailboxInfo.m_image->getTexture()->textureParamsModified();
296 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D;
297
298 WebGraphicsContext3D* webContext = context();
299 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag e->getTextureHandle(true))->fID;
300 webContext->bindTexture(GL_TEXTURE_2D, textureID);
301 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter( ));
302 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter( ));
303 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
304 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
305
306 // Re-use the texture's existing mailbox, if there is one.
307 if (image->getTexture()->getCustomData()) {
308 ASSERT(image->getTexture()->getCustomData()->size() == sizeof(mailboxInf o.m_mailbox.name));
309 memcpy(&mailboxInfo.m_mailbox.name[0], image->getTexture()->getCustomDat a()->data(), sizeof(mailboxInfo.m_mailbox.name));
310 } else {
311 context()->genMailboxCHROMIUM(mailboxInfo.m_mailbox.name);
312 RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&mailboxIn fo.m_mailbox.name[0], sizeof(mailboxInfo.m_mailbox.name)));
313 image->getTexture()->setCustomData(mailboxNameData.get());
314 webContext->produceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo.m_mailbox. name);
315 }
316
317 if (isHidden()) {
318 // With hidden canvases, we release the SkImage immediately because
319 // there is no need for animations to be double buffered.
320 mailboxInfo.m_image.clear();
321 } else {
322 // FIXME: We'd rather insert a syncpoint than perform a flush here,
323 // but currently the canvas will flicker if we don't flush here.
324 const WGC3Duint64 fenceSync = webContext->insertFenceSyncCHROMIUM();
325 webContext->flush();
326 mailboxInfo.m_mailbox.validSyncToken = webContext->genSyncTokenCHROMIUM( fenceSync, mailboxInfo.m_mailbox.syncToken);
327 }
328 webContext->bindTexture(GL_TEXTURE_2D, 0);
329 // Because we are changing the texture binding without going through skia,
330 // we must dirty the context.
331 grContext->resetContext(kTextureBinding_GrGLBackendState);
332
333 *outMailbox = mailboxInfo.m_mailbox;
334 return true;
335 }
336
199 static void hibernateWrapper(WeakPtr<Canvas2DLayerBridge> bridge, double /*idleD eadline*/) 337 static void hibernateWrapper(WeakPtr<Canvas2DLayerBridge> bridge, double /*idleD eadline*/)
200 { 338 {
201 if (bridge) { 339 if (bridge) {
202 bridge->hibernate(); 340 bridge->hibernate();
203 } else { 341 } else {
204 Canvas2DLayerBridge::Logger localLogger; 342 Canvas2DLayerBridge::Logger localLogger;
205 localLogger.reportHibernationEvent(Canvas2DLayerBridge::HibernationAbort edDueToDestructionWhileHibernatePending); 343 localLogger.reportHibernationEvent(Canvas2DLayerBridge::HibernationAbort edDueToDestructionWhileHibernatePending);
206 } 344 }
207 } 345 }
208 346
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 // not care about producing any results for this canvas. 747 // not care about producing any results for this canvas.
610 skipQueuedDrawCommands(); 748 skipQueuedDrawCommands();
611 m_lastImageId = 0; 749 m_lastImageId = 0;
612 return false; 750 return false;
613 } 751 }
614 752
615 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration, SnapshotReasonU nknown); 753 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration, SnapshotReasonU nknown);
616 if (!image || !image->getTexture()) 754 if (!image || !image->getTexture())
617 return false; 755 return false;
618 756
619 WebGraphicsContext3D* webContext = context(); 757 // Early exit if canvas was not drawn to since last prepareMailbox.
620 758 GLenum filter = getGLFilter();
621 // Early exit if canvas was not drawn to since last prepareMailbox
622 GLenum filter = m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_L INEAR;
623 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) 759 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter)
624 return false; 760 return false;
625 m_lastImageId = image->uniqueID(); 761 m_lastImageId = image->uniqueID();
626 m_lastFilter = filter; 762 m_lastFilter = filter;
627 763
628 { 764 return prepareMailboxFromImage(image, outMailbox);
629 MailboxInfo tmp;
630 tmp.m_image = image;
631 tmp.m_parentLayerBridge = this;
632 m_mailboxes.prepend(tmp);
633 }
634 MailboxInfo& mailboxInfo = m_mailboxes.first();
635
636 mailboxInfo.m_mailbox.nearestNeighbor = filter == GL_NEAREST;
637
638 GrContext* grContext = m_contextProvider->grContext();
639 if (!grContext)
640 return true; // for testing: skip gl stuff when using a mock graphics co ntext.
641
642 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled())
643 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode) ;
644
645 // Because of texture sharing with the compositor, we must invalidate
646 // the state cached in skia so that the deferred copy on write
647 // in SkSurface_Gpu does not make any false assumptions.
648 mailboxInfo.m_image->getTexture()->textureParamsModified();
649 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D;
650
651 // Passing true because we need to flush skia's internal queue since texture is about to be accessed directly
652 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag e->getTextureHandle(true))->fID;
653 webContext->bindTexture(GL_TEXTURE_2D, textureID);
654 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
655 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
656 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
657 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
658
659 // Re-use the texture's existing mailbox, if there is one.
660 if (image->getTexture()->getCustomData()) {
661 ASSERT(image->getTexture()->getCustomData()->size() == sizeof(mailboxInf o.m_mailbox.name));
662 memcpy(&mailboxInfo.m_mailbox.name[0], image->getTexture()->getCustomDat a()->data(), sizeof(mailboxInfo.m_mailbox.name));
663 } else {
664 context()->genMailboxCHROMIUM(mailboxInfo.m_mailbox.name);
665 RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&mailboxIn fo.m_mailbox.name[0], sizeof(mailboxInfo.m_mailbox.name)));
666 image->getTexture()->setCustomData(mailboxNameData.get());
667 webContext->produceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo.m_mailbox. name);
668 }
669
670 if (isHidden()) {
671 // With hidden canvases, we release the SkImage immediately because
672 // there is no need for animations to be double buffered.
673 mailboxInfo.m_image.clear();
674 } else {
675 // FIXME: We'd rather insert a syncpoint than perform a flush here,
676 // but currently the canvas will flicker if we don't flush here.
677 const WGC3Duint64 fenceSync = webContext->insertFenceSyncCHROMIUM();
678 webContext->flush();
679 mailboxInfo.m_mailbox.validSyncToken = webContext->genSyncTokenCHROMIUM( fenceSync, mailboxInfo.m_mailbox.syncToken);
680 }
681 webContext->bindTexture(GL_TEXTURE_2D, 0);
682 // Because we are changing the texture binding without going through skia,
683 // we must dirty the context.
684 grContext->resetContext(kTextureBinding_GrGLBackendState);
685
686 *outMailbox = mailboxInfo.m_mailbox;
687 return true;
688 } 765 }
689 766
690 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailb ox, bool lostResource) 767 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailb ox, bool lostResource)
691 { 768 {
692 ASSERT(isAccelerated() || isHibernating()); 769 ASSERT(isAccelerated() || isHibernating());
693 bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->con text3d()->isContextLost()); 770 bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->con text3d()->isContextLost());
694 ASSERT(m_mailboxes.last().m_parentLayerBridge.get() == this); 771 ASSERT(m_mailboxes.last().m_parentLayerBridge.get() == this);
695 772
696 // Mailboxes are typically released in FIFO order, so we iterate 773 // Mailboxes are typically released in FIFO order, so we iterate
697 // from the end of m_mailboxes. 774 // from the end of m_mailboxes.
(...skipping 16 matching lines...) Expand all
714 } 791 }
715 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); 792 GrTexture* texture = releasedMailboxInfo->m_image->getTexture();
716 if (texture) { 793 if (texture) {
717 if (lostResource) { 794 if (lostResource) {
718 texture->abandon(); 795 texture->abandon();
719 } else { 796 } else {
720 texture->textureParamsModified(); 797 texture->textureParamsModified();
721 } 798 }
722 } 799 }
723 } 800 }
801
802 if (releasedMailboxInfo->m_CHROMIUMImageId) {
803 ASSERT(releasedMailboxInfo->m_textureId);
804 ASSERT(!releasedMailboxInfo->m_image);
805 if (mailbox.validSyncToken) {
806 context()->waitSyncTokenCHROMIUM(mailbox.syncToken);
807 }
808
809 WebGraphicsContext3D* webContext = context();
810 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB;
811 webContext->bindTexture(target, releasedMailboxInfo->m_textureId);
812 webContext->releaseTexImage2DCHROMIUM(target, releasedMailboxInfo->m _CHROMIUMImageId);
813 webContext->destroyImageCHROMIUM(releasedMailboxInfo->m_CHROMIUMImag eId);
814 webContext->deleteTexture(releasedMailboxInfo->m_textureId);
815 webContext->bindTexture(target, 0);
816
817 // Because we are changing the texture binding without going through skia,
818 // we must dirty the context.
819 GrContext* grContext = m_contextProvider->grContext();
820 grContext->resetContext(kTextureBinding_GrGLBackendState);
821 }
724 } 822 }
725 823
726 RefPtr<Canvas2DLayerBridge> selfRef; 824 RefPtr<Canvas2DLayerBridge> selfRef;
727 if (m_destructionInProgress) { 825 if (m_destructionInProgress) {
728 // To avoid memory use after free, take a scoped self-reference 826 // To avoid memory use after free, take a scoped self-reference
729 // to postpone destruction until the end of this function. 827 // to postpone destruction until the end of this function.
730 selfRef = this; 828 selfRef = this;
731 } 829 }
732 830
733 // The destruction of 'releasedMailboxInfo' will: 831 // The destruction of 'releasedMailboxInfo' will:
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 void Canvas2DLayerBridge::willOverwriteCanvas() 924 void Canvas2DLayerBridge::willOverwriteCanvas()
827 { 925 {
828 skipQueuedDrawCommands(); 926 skipQueuedDrawCommands();
829 } 927 }
830 928
831 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) 929 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other)
832 { 930 {
833 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); 931 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox));
834 m_image = other.m_image; 932 m_image = other.m_image;
835 m_parentLayerBridge = other.m_parentLayerBridge; 933 m_parentLayerBridge = other.m_parentLayerBridge;
934 m_CHROMIUMImageId = other.m_CHROMIUMImageId;
935 m_textureId = other.m_textureId;
836 } 936 }
837 937
838 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) 938 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event)
839 { 939 {
840 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); 940 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount));
841 hibernationHistogram.count(event); 941 hibernationHistogram.count(event);
842 } 942 }
843 943
844 } // namespace blink 944 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698