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

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

Issue 2212163002: Add some plumbing for the color management of canvases (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor corrections 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) 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 50
51 namespace { 51 namespace {
52 enum { 52 enum {
53 InvalidMailboxIndex = -1, 53 InvalidMailboxIndex = -1,
54 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t wo animation frames behind. 54 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t wo animation frames behind.
55 }; 55 };
56 } // namespace 56 } // namespace
57 57
58 namespace blink { 58 namespace blink {
59 59
60 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, bool* surfaceIsAccelerated) 60 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace, b ool* surfaceIsAccelerated)
61 { 61 {
62 if (gr) 62 if (gr)
63 gr->resetContext(); 63 gr->resetContext();
64 64
65 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre mul_SkAlphaType; 65 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre mul_SkAlphaType;
66 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy pe); 66 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy pe, colorSpace);
67 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); 67 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
68 sk_sp<SkSurface> surface; 68 sk_sp<SkSurface> surface;
69 69
70 if (gr) { 70 if (gr) {
71 *surfaceIsAccelerated = true; 71 *surfaceIsAccelerated = true;
72 surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSam pleCount, Opaque == opacityMode ? 0 : &disableLCDProps); 72 surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSam pleCount, Opaque == opacityMode ? 0 : &disableLCDProps);
73 } 73 }
74 74
75 if (!surface) { 75 if (!surface) {
76 *surfaceIsAccelerated = false; 76 *surfaceIsAccelerated = false;
77 surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disab leLCDProps); 77 surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disab leLCDProps);
78 } 78 }
79 79
80 if (surface) { 80 if (surface) {
81 if (opacityMode == Opaque) { 81 if (opacityMode == Opaque) {
82 surface->getCanvas()->clear(SK_ColorBLACK); 82 surface->getCanvas()->clear(SK_ColorBLACK);
83 } else { 83 } else {
84 surface->getCanvas()->clear(SK_ColorTRANSPARENT); 84 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
85 } 85 }
86 } 86 }
87 return fromSkSp(surface); 87 return fromSkSp(surface);
88 } 88 }
89 89
90 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, AccelerationMode accelerationMode ) 90 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, AccelerationMode accelerationMode , sk_sp<SkColorSpace> colorSpace)
91 { 91 {
92 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL); 92 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL);
93 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P latform::current()->createSharedOffscreenGraphicsContext3DProvider()); 93 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P latform::current()->createSharedOffscreenGraphicsContext3DProvider());
94 if (!contextProvider) 94 if (!contextProvider)
95 return nullptr; 95 return nullptr;
96 RefPtr<Canvas2DLayerBridge> layerBridge; 96 RefPtr<Canvas2DLayerBridge> layerBridge;
97 layerBridge = adoptRef(new Canvas2DLayerBridge(std::move(contextProvider), s ize, msaaSampleCount, opacityMode, accelerationMode)); 97 layerBridge = adoptRef(new Canvas2DLayerBridge(std::move(contextProvider), s ize, msaaSampleCount, opacityMode, accelerationMode, std::move(colorSpace)));
98 return layerBridge.release(); 98 return layerBridge.release();
99 } 99 }
100 100
101 Canvas2DLayerBridge::Canvas2DLayerBridge(std::unique_ptr<WebGraphicsContext3DPro vider> contextProvider, const IntSize& size, int msaaSampleCount, OpacityMode op acityMode, AccelerationMode accelerationMode) 101 Canvas2DLayerBridge::Canvas2DLayerBridge(std::unique_ptr<WebGraphicsContext3DPro vider> contextProvider, const IntSize& size, int msaaSampleCount, OpacityMode op acityMode, AccelerationMode accelerationMode, sk_sp<SkColorSpace> colorSpace)
102 : m_contextProvider(std::move(contextProvider)) 102 : m_contextProvider(std::move(contextProvider))
103 , m_logger(wrapUnique(new Logger)) 103 , m_logger(wrapUnique(new Logger))
104 , m_weakPtrFactory(this) 104 , m_weakPtrFactory(this)
105 , m_imageBuffer(0) 105 , m_imageBuffer(0)
106 , m_msaaSampleCount(msaaSampleCount) 106 , m_msaaSampleCount(msaaSampleCount)
107 , m_bytesAllocated(0) 107 , m_bytesAllocated(0)
108 , m_haveRecordedDrawCommands(false) 108 , m_haveRecordedDrawCommands(false)
109 , m_destructionInProgress(false) 109 , m_destructionInProgress(false)
110 , m_filterQuality(kLow_SkFilterQuality) 110 , m_filterQuality(kLow_SkFilterQuality)
111 , m_isHidden(false) 111 , m_isHidden(false)
112 , m_isDeferralEnabled(true) 112 , m_isDeferralEnabled(true)
113 , m_isRegisteredTaskObserver(false) 113 , m_isRegisteredTaskObserver(false)
114 , m_renderingTaskCompletedForCurrentFrame(false) 114 , m_renderingTaskCompletedForCurrentFrame(false)
115 , m_softwareRenderingWhileHidden(false) 115 , m_softwareRenderingWhileHidden(false)
116 , m_lastImageId(0) 116 , m_lastImageId(0)
117 , m_lastFilter(GL_LINEAR) 117 , m_lastFilter(GL_LINEAR)
118 , m_accelerationMode(accelerationMode) 118 , m_accelerationMode(accelerationMode)
119 , m_opacityMode(opacityMode) 119 , m_opacityMode(opacityMode)
120 , m_size(size) 120 , m_size(size)
121 , m_colorSpace(colorSpace)
121 { 122 {
122 DCHECK(m_contextProvider); 123 DCHECK(m_contextProvider);
123 // Used by browser tests to detect the use of a Canvas2DLayerBridge. 124 // Used by browser tests to detect the use of a Canvas2DLayerBridge.
124 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL); 125 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL);
125 startRecording(); 126 startRecording();
126 } 127 }
127 128
128 Canvas2DLayerBridge::~Canvas2DLayerBridge() 129 Canvas2DLayerBridge::~Canvas2DLayerBridge()
129 { 130 {
130 DCHECK(m_destructionInProgress); 131 DCHECK(m_destructionInProgress);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 return false; 210 return false;
210 211
211 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu reHandle(true))->fID; 212 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu reHandle(true))->fID;
212 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); 213 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
213 214
214 MailboxInfo& info = m_mailboxes.first(); 215 MailboxInfo& info = m_mailboxes.first();
215 info.m_mailbox.textureTarget = GC3D_TEXTURE_RECTANGLE_ARB; 216 info.m_mailbox.textureTarget = GC3D_TEXTURE_RECTANGLE_ARB;
216 gl->GenMailboxCHROMIUM(info.m_mailbox.name); 217 gl->GenMailboxCHROMIUM(info.m_mailbox.name);
217 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, info.m_mailbox.textu reTarget, info.m_mailbox.name); 218 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, info.m_mailbox.textu reTarget, info.m_mailbox.name);
218 info.m_mailbox.allowOverlay = true; 219 info.m_mailbox.allowOverlay = true;
220 info.m_mailbox.colorSpace = m_colorSpace;
219 221
220 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); 222 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
221 gl->Flush(); 223 gl->Flush();
222 gl->GenSyncTokenCHROMIUM(fenceSync, info.m_mailbox.syncToken); 224 gl->GenSyncTokenCHROMIUM(fenceSync, info.m_mailbox.syncToken);
223 info.m_mailbox.validSyncToken = true; 225 info.m_mailbox.validSyncToken = true;
224 226
225 info.m_imageInfo = imageInfo; 227 info.m_imageInfo = imageInfo;
226 *outMailbox = info.m_mailbox; 228 *outMailbox = info.m_mailbox;
227 229
228 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); 230 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode) ; 325 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode) ;
324 326
325 // Need to flush skia's internal queue because texture is about to be access ed directly 327 // Need to flush skia's internal queue because texture is about to be access ed directly
326 grContext->flush(); 328 grContext->flush();
327 329
328 // Because of texture sharing with the compositor, we must invalidate 330 // Because of texture sharing with the compositor, we must invalidate
329 // the state cached in skia so that the deferred copy on write 331 // the state cached in skia so that the deferred copy on write
330 // in SkSurface_Gpu does not make any false assumptions. 332 // in SkSurface_Gpu does not make any false assumptions.
331 mailboxInfo.m_image->getTexture()->textureParamsModified(); 333 mailboxInfo.m_image->getTexture()->textureParamsModified();
332 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D; 334 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D;
335 mailboxInfo.m_mailbox.colorSpace = m_colorSpace.get();
333 336
334 gpu::gles2::GLES2Interface* gl = contextGL(); 337 gpu::gles2::GLES2Interface* gl = contextGL();
335 if (!gl) 338 if (!gl)
336 return false; 339 return false;
337 340
338 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag e->getTextureHandle(true))->fID; 341 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag e->getTextureHandle(true))->fID;
339 gl->BindTexture(GL_TEXTURE_2D, textureID); 342 gl->BindTexture(GL_TEXTURE_2D, textureID);
340 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter()); 343 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter());
341 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter()); 344 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter());
342 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 345 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 return nullptr; // re-creation will happen through restore() 473 return nullptr; // re-creation will happen through restore()
471 } 474 }
472 475
473 bool wantAcceleration = shouldAccelerate(hint); 476 bool wantAcceleration = shouldAccelerate(hint);
474 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati on) { 477 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati on) {
475 wantAcceleration = false; 478 wantAcceleration = false;
476 m_softwareRenderingWhileHidden = true; 479 m_softwareRenderingWhileHidden = true;
477 } 480 }
478 481
479 bool surfaceIsAccelerated; 482 bool surfaceIsAccelerated;
480 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext( ) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated); 483 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext( ) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, m_colorSpace, &surfaceIsA ccelerated);
481 484
482 if (!m_surface) 485 if (!m_surface)
483 reportSurfaceCreationFailure(); 486 reportSurfaceCreationFailure();
484 487
485 if (m_surface && surfaceIsAccelerated && !m_layer) { 488 if (m_surface && surfaceIsAccelerated && !m_layer) {
486 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt ernalTextureLayer(this)); 489 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt ernalTextureLayer(this));
487 m_layer->setOpaque(m_opacityMode == Opaque); 490 m_layer->setOpaque(m_opacityMode == Opaque);
488 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); 491 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque);
489 GraphicsLayer::registerContentsLayer(m_layer->layer()); 492 GraphicsLayer::registerContentsLayer(m_layer->layer());
490 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); 493 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 750
748 gpu::gles2::GLES2Interface* sharedGL = nullptr; 751 gpu::gles2::GLES2Interface* sharedGL = nullptr;
749 m_layer->clearTexture(); 752 m_layer->clearTexture();
750 m_contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGra phicsContext3DProvider()); 753 m_contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGra phicsContext3DProvider());
751 if (m_contextProvider) 754 if (m_contextProvider)
752 sharedGL = m_contextProvider->contextGL(); 755 sharedGL = m_contextProvider->contextGL();
753 756
754 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { 757 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
755 GrContext* grCtx = m_contextProvider->grContext(); 758 GrContext* grCtx = m_contextProvider->grContext();
756 bool surfaceIsAccelerated; 759 bool surfaceIsAccelerated;
757 RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCou nt, m_opacityMode, &surfaceIsAccelerated)); 760 RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCou nt, m_opacityMode, m_colorSpace, &surfaceIsAccelerated));
758 761
759 if (!m_surface) 762 if (!m_surface)
760 reportSurfaceCreationFailure(); 763 reportSurfaceCreationFailure();
761 764
762 // Current paradigm does support switching from accelerated to non-accel erated, which would be tricky 765 // Current paradigm does support switching from accelerated to non-accel erated, which would be tricky
763 // due to changes to the layer tree, which can only happen at specific t imes during the document lifecycle. 766 // due to changes to the layer tree, which can only happen at specific t imes during the document lifecycle.
764 // Therefore, we can only accept the restored surface if it is accelerat ed. 767 // Therefore, we can only accept the restored surface if it is accelerat ed.
765 if (surface && surfaceIsAccelerated) { 768 if (surface && surfaceIsAccelerated) {
766 m_surface = surface.release(); 769 m_surface = surface.release();
767 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 770 // FIXME: draw sad canvas picture into new buffer crbug.com/243842
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 #endif // USE_IOSURFACE_FOR_2D_CANVAS 995 #endif // USE_IOSURFACE_FOR_2D_CANVAS
993 } 996 }
994 997
995 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) 998 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event)
996 { 999 {
997 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); 1000 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount));
998 hibernationHistogram.count(event); 1001 hibernationHistogram.count(event);
999 } 1002 }
1000 1003
1001 } // namespace blink 1004 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698