Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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() | 199 GLenum Canvas2DLayerBridge::getGLFilter() |
| 200 { | 200 { |
| 201 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; | 201 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; |
| 202 } | 202 } |
| 203 | 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 | |
| 204 Canvas2DLayerBridge::MailboxInfo& Canvas2DLayerBridge::createMailboxInfo() | 262 Canvas2DLayerBridge::MailboxInfo& Canvas2DLayerBridge::createMailboxInfo() |
| 205 { | 263 { |
| 206 MailboxInfo tmp; | 264 MailboxInfo tmp; |
| 207 tmp.m_parentLayerBridge = this; | 265 tmp.m_parentLayerBridge = this; |
| 208 m_mailboxes.prepend(tmp); | 266 m_mailboxes.prepend(tmp); |
| 209 MailboxInfo& mailboxInfo = m_mailboxes.first(); | 267 MailboxInfo& mailboxInfo = m_mailboxes.first(); |
| 210 return mailboxInfo; | 268 return mailboxInfo; |
| 211 } | 269 } |
| 212 | 270 |
| 213 bool Canvas2DLayerBridge::prepareMailboxFromImage(RefPtr<SkImage>& image, WebExt ernalTextureMailbox* outMailbox) | 271 bool Canvas2DLayerBridge::prepareMailboxFromImage(RefPtr<SkImage>& image, WebExt ernalTextureMailbox* outMailbox) |
| 214 { | 272 { |
| 273 GrContext* grContext = m_contextProvider->grContext(); | |
| 274 if (RuntimeEnabledFeatures::canvas2dImageChromiumEnabled()) { | |
| 275 if (grContext && prepareIOSurfaceMailboxFromImage(image, outMailbox)) | |
|
Justin Novosad
2016/03/02 16:33:45
I think what you want here is:
if (!grContext)
| |
| 276 return true; | |
| 277 } | |
| 278 | |
| 215 MailboxInfo& mailboxInfo = createMailboxInfo(); | 279 MailboxInfo& mailboxInfo = createMailboxInfo(); |
| 216 mailboxInfo.m_mailbox.nearestNeighbor = getGLFilter() == GL_NEAREST; | 280 mailboxInfo.m_mailbox.nearestNeighbor = getGLFilter() == GL_NEAREST; |
| 217 mailboxInfo.m_image = image; | 281 mailboxInfo.m_image = image; |
| 218 | 282 |
| 219 GrContext* grContext = m_contextProvider->grContext(); | |
| 220 if (!grContext) | 283 if (!grContext) |
| 221 return true; // for testing: skip gl stuff when using a mock graphics co ntext. | 284 return true; // for testing: skip gl stuff when using a mock graphics co ntext. |
| 222 | 285 |
| 223 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled()) | 286 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled()) |
| 224 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode) ; | 287 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode) ; |
| 225 | 288 |
| 226 // Need to flush skia's internal queue because texture is about to be access ed directly | 289 // Need to flush skia's internal queue because texture is about to be access ed directly |
| 227 grContext->flush(); | 290 grContext->flush(); |
| 228 | 291 |
| 229 // Because of texture sharing with the compositor, we must invalidate | 292 // Because of texture sharing with the compositor, we must invalidate |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 while (true) { | 778 while (true) { |
| 716 --releasedMailboxInfo; | 779 --releasedMailboxInfo; |
| 717 if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) { | 780 if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) { |
| 718 break; | 781 break; |
| 719 } | 782 } |
| 720 ASSERT(releasedMailboxInfo != firstMailbox); | 783 ASSERT(releasedMailboxInfo != firstMailbox); |
| 721 } | 784 } |
| 722 | 785 |
| 723 if (!contextLost) { | 786 if (!contextLost) { |
| 724 // Invalidate texture state in case the compositor altered it since the copy-on-write. | 787 // Invalidate texture state in case the compositor altered it since the copy-on-write. |
| 725 if (releasedMailboxInfo->m_image) { | 788 if (releasedMailboxInfo->m_image) { |
|
Justin Novosad
2016/03/02 16:33:45
ASSERT(!releasedMailboxInfo->m_CHROMIUMImageId)
| |
| 726 if (mailbox.validSyncToken) { | 789 if (mailbox.validSyncToken) { |
| 727 context()->waitSyncTokenCHROMIUM(mailbox.syncToken); | 790 context()->waitSyncTokenCHROMIUM(mailbox.syncToken); |
| 728 } | 791 } |
| 729 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); | 792 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); |
| 730 if (texture) { | 793 if (texture) { |
| 731 if (lostResource) { | 794 if (lostResource) { |
| 732 texture->abandon(); | 795 texture->abandon(); |
| 733 } else { | 796 } else { |
| 734 texture->textureParamsModified(); | 797 texture->textureParamsModified(); |
| 735 } | 798 } |
| 736 } | 799 } |
| 737 } | 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); | |
|
Justin Novosad
2016/03/02 16:33:45
This synchronisation is probably unnecessary? In t
| |
| 807 } | |
| 808 | |
| 809 WebGraphicsContext3D* webContext = context(); | |
| 810 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB; | |
|
Justin Novosad
2016/03/02 16:33:45
Does the extension for this need to be detected?
| |
| 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 } | |
| 738 } | 822 } |
| 739 | 823 |
| 740 RefPtr<Canvas2DLayerBridge> selfRef; | 824 RefPtr<Canvas2DLayerBridge> selfRef; |
| 741 if (m_destructionInProgress) { | 825 if (m_destructionInProgress) { |
| 742 // To avoid memory use after free, take a scoped self-reference | 826 // To avoid memory use after free, take a scoped self-reference |
| 743 // to postpone destruction until the end of this function. | 827 // to postpone destruction until the end of this function. |
| 744 selfRef = this; | 828 selfRef = this; |
| 745 } | 829 } |
| 746 | 830 |
| 747 // The destruction of 'releasedMailboxInfo' will: | 831 // The destruction of 'releasedMailboxInfo' will: |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 840 void Canvas2DLayerBridge::willOverwriteCanvas() | 924 void Canvas2DLayerBridge::willOverwriteCanvas() |
| 841 { | 925 { |
| 842 skipQueuedDrawCommands(); | 926 skipQueuedDrawCommands(); |
| 843 } | 927 } |
| 844 | 928 |
| 845 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) | 929 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) |
| 846 { | 930 { |
| 847 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); | 931 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); |
| 848 m_image = other.m_image; | 932 m_image = other.m_image; |
| 849 m_parentLayerBridge = other.m_parentLayerBridge; | 933 m_parentLayerBridge = other.m_parentLayerBridge; |
| 934 m_CHROMIUMImageId = other.m_CHROMIUMImageId; | |
| 935 m_textureId = other.m_textureId; | |
| 850 } | 936 } |
| 851 | 937 |
| 852 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) | 938 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) |
| 853 { | 939 { |
| 854 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); | 940 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); |
| 855 hibernationHistogram.count(event); | 941 hibernationHistogram.count(event); |
| 856 } | 942 } |
| 857 | 943 |
| 858 } // namespace blink | 944 } // namespace blink |
| OLD | NEW |