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

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

Issue 2364633003: color: Set GpuMemoryBuffer color spaces for Canvas (Closed)
Patch Set: Fix constexpr Created 4 years, 2 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 11 matching lines...) Expand all
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "platform/graphics/Canvas2DLayerBridge.h" 26 #include "platform/graphics/Canvas2DLayerBridge.h"
27 27
28 #include "base/memory/ptr_util.h" 28 #include "base/memory/ptr_util.h"
29 #include "cc/resources/single_release_callback.h" 29 #include "cc/resources/single_release_callback.h"
30 #include "cc/resources/texture_mailbox.h" 30 #include "cc/resources/texture_mailbox.h"
31 #include "gpu/command_buffer/client/gles2_interface.h" 31 #include "gpu/command_buffer/client/gles2_interface.h"
32 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
32 #include "platform/Histogram.h" 33 #include "platform/Histogram.h"
33 #include "platform/RuntimeEnabledFeatures.h" 34 #include "platform/RuntimeEnabledFeatures.h"
34 #include "platform/TraceEvent.h" 35 #include "platform/TraceEvent.h"
35 #include "platform/graphics/CanvasMetrics.h" 36 #include "platform/graphics/CanvasMetrics.h"
36 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" 37 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
37 #include "platform/graphics/GraphicsLayer.h" 38 #include "platform/graphics/GraphicsLayer.h"
38 #include "platform/graphics/ImageBuffer.h" 39 #include "platform/graphics/ImageBuffer.h"
39 #include "platform/graphics/gpu/SharedContextRateLimiter.h" 40 #include "platform/graphics/gpu/SharedContextRateLimiter.h"
40 #include "public/platform/Platform.h" 41 #include "public/platform/Platform.h"
41 #include "public/platform/WebCompositorSupport.h" 42 #include "public/platform/WebCompositorSupport.h"
(...skipping 11 matching lines...) Expand all
53 54
54 namespace { 55 namespace {
55 enum { 56 enum {
56 InvalidMailboxIndex = -1, 57 InvalidMailboxIndex = -1,
57 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t wo animation frames behind. 58 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t wo animation frames behind.
58 }; 59 };
59 } // namespace 60 } // namespace
60 61
61 namespace blink { 62 namespace blink {
62 63
64 #if USE_IOSURFACE_FOR_2D_CANVAS
65 struct Canvas2DLayerBridge::ImageInfo : public RefCounted<ImageInfo> {
66 ImageInfo(std::unique_ptr<gfx::GpuMemoryBuffer>, GLuint imageId, GLuint text ureId);
67 ~ImageInfo();
68
69 // The backing buffer.
70 std::unique_ptr<gfx::GpuMemoryBuffer> m_gpuMemoryBuffer;
71
72 // The id of the CHROMIUM image.
73 const GLuint m_imageId;
74
75 // The id of the texture bound to the CHROMIUM image.
76 const GLuint m_textureId;
77 };
78 #endif // USE_IOSURFACE_FOR_2D_CANVAS
79
63 static sk_sp<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace, bool* surfaceIsAccelerated) 80 static sk_sp<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace, bool* surfaceIsAccelerated)
64 { 81 {
65 if (gr) 82 if (gr)
66 gr->resetContext(); 83 gr->resetContext();
67 84
68 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre mul_SkAlphaType; 85 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre mul_SkAlphaType;
69 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy pe, colorSpace); 86 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy pe, colorSpace);
70 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); 87 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
71 sk_sp<SkSurface> surface; 88 sk_sp<SkSurface> surface;
72 89
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; 204 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR;
188 } 205 }
189 206
190 #if USE_IOSURFACE_FOR_2D_CANVAS 207 #if USE_IOSURFACE_FOR_2D_CANVAS
191 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage(SkImage* image, cc::T extureMailbox* outMailbox) 208 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage(SkImage* image, cc::T extureMailbox* outMailbox)
192 { 209 {
193 // Need to flush skia's internal queue because texture is about to be access ed directly 210 // Need to flush skia's internal queue because texture is about to be access ed directly
194 GrContext* grContext = m_contextProvider->grContext(); 211 GrContext* grContext = m_contextProvider->grContext();
195 grContext->flush(); 212 grContext->flush();
196 213
197 ImageInfo imageInfo = createIOSurfaceBackedTexture(); 214 RefPtr<ImageInfo> imageInfo = createIOSurfaceBackedTexture();
198 if (imageInfo.empty()) 215 if (!imageInfo)
199 return false; 216 return false;
200 217
201 gpu::gles2::GLES2Interface* gl = contextGL(); 218 gpu::gles2::GLES2Interface* gl = contextGL();
202 if (!gl) 219 if (!gl)
203 return false; 220 return false;
204 221
205 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu reHandle(true))->fID; 222 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu reHandle(true))->fID;
206 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); 223 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo->m_textureId, 0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
207 224
208 MailboxInfo& info = m_mailboxes.first(); 225 MailboxInfo& info = m_mailboxes.first();
209 uint32_t textureTarget = GC3D_TEXTURE_RECTANGLE_ARB; 226 uint32_t textureTarget = GC3D_TEXTURE_RECTANGLE_ARB;
210 gpu::Mailbox mailbox; 227 gpu::Mailbox mailbox;
211 gl->GenMailboxCHROMIUM(mailbox.name); 228 gl->GenMailboxCHROMIUM(mailbox.name);
212 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, textureTarget, mailb ox.name); 229 gl->ProduceTextureDirectCHROMIUM(imageInfo->m_textureId, textureTarget, mail box.name);
213 230
214 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); 231 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
215 gl->Flush(); 232 gl->Flush();
216 gpu::SyncToken syncToken; 233 gpu::SyncToken syncToken;
217 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); 234 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
218 235
219 info.m_imageInfo = imageInfo; 236 info.m_imageInfo = imageInfo;
220 bool isOverlayCandidate = true; 237 bool isOverlayCandidate = true;
221 bool secureOutputOnly = false; 238 bool secureOutputOnly = false;
222 info.m_mailbox = mailbox; 239 info.m_mailbox = mailbox;
223 *outMailbox = cc::TextureMailbox(mailbox, syncToken, textureTarget, gfx::Siz e(m_size.width(), m_size.height()), isOverlayCandidate, secureOutputOnly); 240
241 *outMailbox = cc::TextureMailbox(mailbox, syncToken, textureTarget, gfx::Siz e(m_size), isOverlayCandidate, secureOutputOnly);
242 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) {
243 gfx::ColorSpace colorSpace = gfx::ColorSpace::FromSkColorSpace(m_colorSp ace);
244 outMailbox->set_color_space(colorSpace);
245 imageInfo->m_gpuMemoryBuffer->SetColorSpaceForScanout(colorSpace);
246 }
224 247
225 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); 248 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0);
226 249
227 // Because we are changing the texture binding without going through skia, 250 // Because we are changing the texture binding without going through skia,
228 // we must dirty the context. 251 // we must dirty the context.
229 grContext->resetContext(kTextureBinding_GrGLBackendState); 252 grContext->resetContext(kTextureBinding_GrGLBackendState);
230 253
231 return true; 254 return true;
232 } 255 }
233 256
234 Canvas2DLayerBridge::ImageInfo Canvas2DLayerBridge::createIOSurfaceBackedTexture () 257 RefPtr<Canvas2DLayerBridge::ImageInfo> Canvas2DLayerBridge::createIOSurfaceBacke dTexture()
235 { 258 {
236 if (!m_imageInfoCache.isEmpty()) { 259 if (!m_imageInfoCache.isEmpty()) {
237 Canvas2DLayerBridge::ImageInfo info = m_imageInfoCache.last(); 260 RefPtr<Canvas2DLayerBridge::ImageInfo> info = m_imageInfoCache.last();
238 m_imageInfoCache.removeLast(); 261 m_imageInfoCache.removeLast();
239 return info; 262 return info;
240 } 263 }
241 264
242 gpu::gles2::GLES2Interface* gl = contextGL(); 265 gpu::gles2::GLES2Interface* gl = contextGL();
243 if (!gl) 266 if (!gl)
244 return Canvas2DLayerBridge::ImageInfo(); 267 return nullptr;
245 268
246 GLuint imageId = gl->CreateGpuMemoryBufferImageCHROMIUM(m_size.width(), m_si ze.height(), GL_RGBA, GC3D_SCANOUT_CHROMIUM); 269 gpu::GpuMemoryBufferManager* gpuMemoryBufferManager = Platform::current()->g etGpuMemoryBufferManager();
270 if (!gpuMemoryBufferManager)
271 return nullptr;
272
273 std::unique_ptr<gfx::GpuMemoryBuffer> gpuMemoryBuffer = gpuMemoryBufferManag er->AllocateGpuMemoryBuffer(
274 gfx::Size(m_size), gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::SCANO UT, gpu::kNullSurfaceHandle);
275 if (!gpuMemoryBuffer)
276 return nullptr;
277
278 GLuint imageId = gl->CreateImageCHROMIUM(
279 gpuMemoryBuffer->AsClientBuffer(), m_size.width(), m_size.height(), GL_R GBA);
247 if (!imageId) 280 if (!imageId)
248 return Canvas2DLayerBridge::ImageInfo(); 281 return nullptr;
249 282
250 GLuint textureId; 283 GLuint textureId;
251 gl->GenTextures(1, &textureId); 284 gl->GenTextures(1, &textureId);
252 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB; 285 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB;
253 gl->BindTexture(target, textureId); 286 gl->BindTexture(target, textureId);
254 gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, getGLFilter()); 287 gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, getGLFilter());
255 gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, getGLFilter()); 288 gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, getGLFilter());
256 gl->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 289 gl->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
257 gl->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 290 gl->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
258 gl->BindTexImage2DCHROMIUM(target, imageId); 291 gl->BindTexImage2DCHROMIUM(target, imageId);
259 292
260 return Canvas2DLayerBridge::ImageInfo(imageId, textureId); 293 return adoptRef(new Canvas2DLayerBridge::ImageInfo(std::move(gpuMemoryBuffer ), imageId, textureId));
261 } 294 }
262 295
263 void Canvas2DLayerBridge::deleteCHROMIUMImage(ImageInfo info) 296 void Canvas2DLayerBridge::deleteCHROMIUMImage(RefPtr<ImageInfo> info)
264 { 297 {
265 gpu::gles2::GLES2Interface* gl = contextGL(); 298 gpu::gles2::GLES2Interface* gl = contextGL();
266 if (!gl) 299 if (!gl)
267 return; 300 return;
268 301
269 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB; 302 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB;
270 gl->BindTexture(target, info.m_textureId); 303 gl->BindTexture(target, info->m_textureId);
271 gl->ReleaseTexImage2DCHROMIUM(target, info.m_imageId); 304 gl->ReleaseTexImage2DCHROMIUM(target, info->m_imageId);
272 gl->DestroyImageCHROMIUM(info.m_imageId); 305 gl->DestroyImageCHROMIUM(info->m_imageId);
273 gl->DeleteTextures(1, &info.m_textureId); 306 gl->DeleteTextures(1, &info->m_textureId);
274 gl->BindTexture(target, 0); 307 gl->BindTexture(target, 0);
308 info->m_gpuMemoryBuffer.reset();
275 309
276 resetSkiaTextureBinding(); 310 resetSkiaTextureBinding();
277 } 311 }
278 312
279 void Canvas2DLayerBridge::clearCHROMIUMImageCache() 313 void Canvas2DLayerBridge::clearCHROMIUMImageCache()
280 { 314 {
281 for (const auto& it : m_imageInfoCache) { 315 for (const auto& it : m_imageInfoCache) {
282 deleteCHROMIUMImage(it); 316 deleteCHROMIUMImage(it);
283 } 317 }
284 m_imageInfoCache.clear(); 318 m_imageInfoCache.clear();
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 --releasedMailboxInfo; 888 --releasedMailboxInfo;
855 if (releasedMailboxInfo->m_mailbox == mailbox) 889 if (releasedMailboxInfo->m_mailbox == mailbox)
856 break; 890 break;
857 DCHECK(releasedMailboxInfo != firstMailbox); 891 DCHECK(releasedMailboxInfo != firstMailbox);
858 } 892 }
859 893
860 if (!contextLost) { 894 if (!contextLost) {
861 // Invalidate texture state in case the compositor altered it since the copy-on-write. 895 // Invalidate texture state in case the compositor altered it since the copy-on-write.
862 if (releasedMailboxInfo->m_image) { 896 if (releasedMailboxInfo->m_image) {
863 #if USE_IOSURFACE_FOR_2D_CANVAS 897 #if USE_IOSURFACE_FOR_2D_CANVAS
864 DCHECK(releasedMailboxInfo->m_imageInfo.empty()); 898 DCHECK(!releasedMailboxInfo->m_imageInfo);
865 #endif // USE_IOSURFACE_FOR_2D_CANVAS 899 #endif // USE_IOSURFACE_FOR_2D_CANVAS
866 if (syncToken.HasData()) { 900 if (syncToken.HasData()) {
867 contextGL()->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); 901 contextGL()->WaitSyncTokenCHROMIUM(syncToken.GetConstData());
868 } 902 }
869 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); 903 GrTexture* texture = releasedMailboxInfo->m_image->getTexture();
870 if (texture) { 904 if (texture) {
871 if (lostResource) { 905 if (lostResource) {
872 texture->abandon(); 906 texture->abandon();
873 } else { 907 } else {
874 texture->textureParamsModified(); 908 texture->textureParamsModified();
875 // Break the mailbox association to avoid leaking mailboxes every time skia recycles a texture. 909 // Break the mailbox association to avoid leaking mailboxes every time skia recycles a texture.
876 gpu::gles2::GLES2Interface* gl = contextGL(); 910 gpu::gles2::GLES2Interface* gl = contextGL();
877 if (gl) 911 if (gl)
878 gl->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, relea sedMailboxInfo->m_mailbox.name); 912 gl->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, relea sedMailboxInfo->m_mailbox.name);
879 } 913 }
880 } 914 }
881 } 915 }
882 916
883 #if USE_IOSURFACE_FOR_2D_CANVAS 917 #if USE_IOSURFACE_FOR_2D_CANVAS
884 if (!releasedMailboxInfo->m_imageInfo.empty() && !lostResource) { 918 if (releasedMailboxInfo->m_imageInfo && !lostResource) {
885 m_imageInfoCache.append(releasedMailboxInfo->m_imageInfo); 919 m_imageInfoCache.append(releasedMailboxInfo->m_imageInfo);
886 } 920 }
887 #endif // USE_IOSURFACE_FOR_2D_CANVAS 921 #endif // USE_IOSURFACE_FOR_2D_CANVAS
888 } 922 }
889 923
890 RefPtr<Canvas2DLayerBridge> selfRef; 924 RefPtr<Canvas2DLayerBridge> selfRef;
891 if (m_destructionInProgress) { 925 if (m_destructionInProgress) {
892 // To avoid memory use after free, take a scoped self-reference 926 // To avoid memory use after free, take a scoped self-reference
893 // to postpone destruction until the end of this function. 927 // to postpone destruction until the end of this function.
894 selfRef = this; 928 selfRef = this;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 getOrCreateSurface()->notifyContentWillChange(SkSurface::kRetain_ContentChan geMode); 1025 getOrCreateSurface()->notifyContentWillChange(SkSurface::kRetain_ContentChan geMode);
992 return m_surface->makeImageSnapshot(); 1026 return m_surface->makeImageSnapshot();
993 } 1027 }
994 1028
995 void Canvas2DLayerBridge::willOverwriteCanvas() 1029 void Canvas2DLayerBridge::willOverwriteCanvas()
996 { 1030 {
997 skipQueuedDrawCommands(); 1031 skipQueuedDrawCommands();
998 } 1032 }
999 1033
1000 #if USE_IOSURFACE_FOR_2D_CANVAS 1034 #if USE_IOSURFACE_FOR_2D_CANVAS
1001 Canvas2DLayerBridge::ImageInfo::ImageInfo(GLuint imageId, GLuint textureId) : m_ imageId(imageId), m_textureId(textureId) 1035 Canvas2DLayerBridge::ImageInfo::ImageInfo(std::unique_ptr<gfx::GpuMemoryBuffer> gpuMemoryBuffer, GLuint imageId, GLuint textureId)
1036 : m_gpuMemoryBuffer(std::move(gpuMemoryBuffer))
1037 , m_imageId(imageId)
1038 , m_textureId(textureId)
1002 { 1039 {
1003 DCHECK(imageId); 1040 DCHECK(m_gpuMemoryBuffer);
1004 DCHECK(textureId); 1041 DCHECK(m_imageId);
1042 DCHECK(m_textureId);
1005 } 1043 }
1006 1044
1007 bool Canvas2DLayerBridge::ImageInfo::empty() 1045 Canvas2DLayerBridge::ImageInfo::~ImageInfo()
1008 { 1046 {
1009 return m_imageId == 0;
1010 } 1047 }
1011 #endif // USE_IOSURFACE_FOR_2D_CANVAS 1048 #endif // USE_IOSURFACE_FOR_2D_CANVAS
1012 1049
1013 Canvas2DLayerBridge::MailboxInfo::MailboxInfo() = default; 1050 Canvas2DLayerBridge::MailboxInfo::MailboxInfo() = default;
1014 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) = defaul t; 1051 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) = defaul t;
1015 1052
1016 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) 1053 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event)
1017 { 1054 {
1018 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); 1055 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount));
1019 hibernationHistogram.count(event); 1056 hibernationHistogram.count(event);
1020 } 1057 }
1021 1058
1022 } // namespace blink 1059 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698