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

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: rebase again Created 4 years, 3 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 namespace { 54 namespace {
55 enum { 55 enum {
56 InvalidMailboxIndex = -1, 56 InvalidMailboxIndex = -1,
57 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t wo animation frames behind. 57 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t wo animation frames behind.
58 }; 58 };
59 } // namespace 59 } // namespace
60 60
61 namespace blink { 61 namespace blink {
62 62
63 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, bool* surfaceIsAccelerated) 63 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace, b ool* surfaceIsAccelerated)
64 { 64 {
65 if (gr) 65 if (gr)
66 gr->resetContext(); 66 gr->resetContext();
67 67
68 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre mul_SkAlphaType; 68 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre mul_SkAlphaType;
69 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy pe); 69 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy pe, colorSpace);
70 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); 70 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
71 sk_sp<SkSurface> surface; 71 sk_sp<SkSurface> surface;
72 72
73 if (gr) { 73 if (gr) {
74 *surfaceIsAccelerated = true; 74 *surfaceIsAccelerated = true;
75 surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSam pleCount, Opaque == opacityMode ? 0 : &disableLCDProps); 75 surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSam pleCount, Opaque == opacityMode ? 0 : &disableLCDProps);
76 } 76 }
77 77
78 if (!surface) { 78 if (!surface) {
79 *surfaceIsAccelerated = false; 79 *surfaceIsAccelerated = false;
80 surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disab leLCDProps); 80 surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disab leLCDProps);
81 } 81 }
82 82
83 if (surface) { 83 if (surface) {
84 if (opacityMode == Opaque) { 84 if (opacityMode == Opaque) {
85 surface->getCanvas()->clear(SK_ColorBLACK); 85 surface->getCanvas()->clear(SK_ColorBLACK);
86 } else { 86 } else {
87 surface->getCanvas()->clear(SK_ColorTRANSPARENT); 87 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
88 } 88 }
89 } 89 }
90 return fromSkSp(surface); 90 return fromSkSp(surface);
91 } 91 }
92 92
93 Canvas2DLayerBridge::Canvas2DLayerBridge(std::unique_ptr<WebGraphicsContext3DPro vider> contextProvider, const IntSize& size, int msaaSampleCount, OpacityMode op acityMode, AccelerationMode accelerationMode) 93 Canvas2DLayerBridge::Canvas2DLayerBridge(std::unique_ptr<WebGraphicsContext3DPro vider> contextProvider, const IntSize& size, int msaaSampleCount, OpacityMode op acityMode, AccelerationMode accelerationMode, sk_sp<SkColorSpace> colorSpace)
94 : m_contextProvider(std::move(contextProvider)) 94 : m_contextProvider(std::move(contextProvider))
95 , m_logger(wrapUnique(new Logger)) 95 , m_logger(wrapUnique(new Logger))
96 , m_weakPtrFactory(this) 96 , m_weakPtrFactory(this)
97 , m_imageBuffer(0) 97 , m_imageBuffer(0)
98 , m_msaaSampleCount(msaaSampleCount) 98 , m_msaaSampleCount(msaaSampleCount)
99 , m_bytesAllocated(0) 99 , m_bytesAllocated(0)
100 , m_haveRecordedDrawCommands(false) 100 , m_haveRecordedDrawCommands(false)
101 , m_destructionInProgress(false) 101 , m_destructionInProgress(false)
102 , m_filterQuality(kLow_SkFilterQuality) 102 , m_filterQuality(kLow_SkFilterQuality)
103 , m_isHidden(false) 103 , m_isHidden(false)
104 , m_isDeferralEnabled(true) 104 , m_isDeferralEnabled(true)
105 , m_isRegisteredTaskObserver(false) 105 , m_isRegisteredTaskObserver(false)
106 , m_renderingTaskCompletedForCurrentFrame(false) 106 , m_renderingTaskCompletedForCurrentFrame(false)
107 , m_softwareRenderingWhileHidden(false) 107 , m_softwareRenderingWhileHidden(false)
108 , m_lastImageId(0) 108 , m_lastImageId(0)
109 , m_lastFilter(GL_LINEAR) 109 , m_lastFilter(GL_LINEAR)
110 , m_accelerationMode(accelerationMode) 110 , m_accelerationMode(accelerationMode)
111 , m_opacityMode(opacityMode) 111 , m_opacityMode(opacityMode)
112 , m_size(size) 112 , m_size(size)
113 , m_colorSpace(colorSpace)
113 { 114 {
114 DCHECK(m_contextProvider); 115 DCHECK(m_contextProvider);
115 DCHECK(!m_contextProvider->isSoftwareRendering()); 116 DCHECK(!m_contextProvider->isSoftwareRendering());
116 // Used by browser tests to detect the use of a Canvas2DLayerBridge. 117 // Used by browser tests to detect the use of a Canvas2DLayerBridge.
117 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL); 118 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL);
118 startRecording(); 119 startRecording();
119 } 120 }
120 121
121 Canvas2DLayerBridge::~Canvas2DLayerBridge() 122 Canvas2DLayerBridge::~Canvas2DLayerBridge()
122 { 123 {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 return nullptr; // re-creation will happen through restore() 459 return nullptr; // re-creation will happen through restore()
459 } 460 }
460 461
461 bool wantAcceleration = shouldAccelerate(hint); 462 bool wantAcceleration = shouldAccelerate(hint);
462 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati on) { 463 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati on) {
463 wantAcceleration = false; 464 wantAcceleration = false;
464 m_softwareRenderingWhileHidden = true; 465 m_softwareRenderingWhileHidden = true;
465 } 466 }
466 467
467 bool surfaceIsAccelerated; 468 bool surfaceIsAccelerated;
468 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext( ) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated); 469 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext( ) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, m_colorSpace, &surfaceIsA ccelerated);
469 470
470 if (!m_surface) 471 if (!m_surface)
471 reportSurfaceCreationFailure(); 472 reportSurfaceCreationFailure();
472 473
473 if (m_surface && surfaceIsAccelerated && !m_layer) { 474 if (m_surface && surfaceIsAccelerated && !m_layer) {
474 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt ernalTextureLayer(this)); 475 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt ernalTextureLayer(this));
475 m_layer->setOpaque(m_opacityMode == Opaque); 476 m_layer->setOpaque(m_opacityMode == Opaque);
476 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); 477 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque);
477 GraphicsLayer::registerContentsLayer(m_layer->layer()); 478 GraphicsLayer::registerContentsLayer(m_layer->layer());
478 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); 479 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 736
736 gpu::gles2::GLES2Interface* sharedGL = nullptr; 737 gpu::gles2::GLES2Interface* sharedGL = nullptr;
737 m_layer->clearTexture(); 738 m_layer->clearTexture();
738 m_contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGra phicsContext3DProvider()); 739 m_contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGra phicsContext3DProvider());
739 if (m_contextProvider) 740 if (m_contextProvider)
740 sharedGL = m_contextProvider->contextGL(); 741 sharedGL = m_contextProvider->contextGL();
741 742
742 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { 743 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
743 GrContext* grCtx = m_contextProvider->grContext(); 744 GrContext* grCtx = m_contextProvider->grContext();
744 bool surfaceIsAccelerated; 745 bool surfaceIsAccelerated;
745 RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCou nt, m_opacityMode, &surfaceIsAccelerated)); 746 RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCou nt, m_opacityMode, m_colorSpace, &surfaceIsAccelerated));
746 747
747 if (!m_surface) 748 if (!m_surface)
748 reportSurfaceCreationFailure(); 749 reportSurfaceCreationFailure();
749 750
750 // Current paradigm does support switching from accelerated to non-accel erated, which would be tricky 751 // Current paradigm does support switching from accelerated to non-accel erated, which would be tricky
751 // due to changes to the layer tree, which can only happen at specific t imes during the document lifecycle. 752 // due to changes to the layer tree, which can only happen at specific t imes during the document lifecycle.
752 // Therefore, we can only accept the restored surface if it is accelerat ed. 753 // Therefore, we can only accept the restored surface if it is accelerat ed.
753 if (surface && surfaceIsAccelerated) { 754 if (surface && surfaceIsAccelerated) {
754 m_surface = surface.release(); 755 m_surface = surface.release();
755 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 756 // FIXME: draw sad canvas picture into new buffer crbug.com/243842
756 } 757 }
757 } 758 }
758 if (m_imageBuffer) 759 if (m_imageBuffer)
759 m_imageBuffer->updateGPUMemoryUsage(); 760 m_imageBuffer->updateGPUMemoryUsage();
760 761
761 return m_surface.get(); 762 return m_surface.get();
762 } 763 }
763 764
765 static gfx::ColorSpace SkColorSpaceToColorSpace(const SkColorSpace* skColorSpace )
766 {
767 // TODO(crbug.com/634102): Eliminate this clumsy conversion by unifying
768 // SkColorSpace and gfx::ColorSpace.
769 if (!skColorSpace)
770 return gfx::ColorSpace();
771
772 gfx::ColorSpace::TransferID transferID = gfx::ColorSpace::TransferID::UNSPEC IFIED;
773 switch (skColorSpace->gammaNamed()) {
774 case SkColorSpace::kSRGB_GammaNamed:
775 transferID = gfx::ColorSpace::TransferID::IEC61966_2_1;
776 break;
777 case SkColorSpace::kLinear_GammaNamed:
778 transferID = gfx::ColorSpace::TransferID::LINEAR;
779 break;
780 default:
781 // TODO(crbug.com/634102): Not all curve type are supported
782 DCHECK(false);
783 }
784
785 // TODO(crbug.com/634102): No primary conversions are performed.
786 // Rec-709 is assumed.
787 return gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT709, transferID, gfx::C olorSpace::MatrixID::RGB, gfx::ColorSpace::RangeID::FULL);
788 }
789
764 bool Canvas2DLayerBridge::PrepareTextureMailbox( 790 bool Canvas2DLayerBridge::PrepareTextureMailbox(
765 cc::TextureMailbox* outMailbox, 791 cc::TextureMailbox* outMailbox,
766 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) 792 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback)
767 { 793 {
768 if (m_destructionInProgress) { 794 if (m_destructionInProgress) {
769 // It can be hit in the following sequence. 795 // It can be hit in the following sequence.
770 // 1. Canvas draws something. 796 // 1. Canvas draws something.
771 // 2. The compositor begins the frame. 797 // 2. The compositor begins the frame.
772 // 3. Javascript makes a context be lost. 798 // 3. Javascript makes a context be lost.
773 // 4. Here. 799 // 4. Here.
(...skipping 19 matching lines...) Expand all
793 // Early exit if canvas was not drawn to since last prepareMailbox. 819 // Early exit if canvas was not drawn to since last prepareMailbox.
794 GLenum filter = getGLFilter(); 820 GLenum filter = getGLFilter();
795 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) 821 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter)
796 return false; 822 return false;
797 m_lastImageId = image->uniqueID(); 823 m_lastImageId = image->uniqueID();
798 m_lastFilter = filter; 824 m_lastFilter = filter;
799 825
800 if (!prepareMailboxFromImage(image.release(), outMailbox)) 826 if (!prepareMailboxFromImage(image.release(), outMailbox))
801 return false; 827 return false;
802 outMailbox->set_nearest_neighbor(getGLFilter() == GL_NEAREST); 828 outMailbox->set_nearest_neighbor(getGLFilter() == GL_NEAREST);
829 gfx::ColorSpace colorSpace = SkColorSpaceToColorSpace(m_colorSpace.get());
830 outMailbox->set_color_space(colorSpace);
803 831
804 auto func = WTF::bind(&Canvas2DLayerBridge::mailboxReleased, 832 auto func = WTF::bind(&Canvas2DLayerBridge::mailboxReleased,
805 m_weakPtrFactory.createWeakPtr(), 833 m_weakPtrFactory.createWeakPtr(),
806 outMailbox->mailbox()); 834 outMailbox->mailbox());
807 *outReleaseCallback = cc::SingleReleaseCallback::Create( 835 *outReleaseCallback = cc::SingleReleaseCallback::Create(
808 convertToBaseCallback(std::move(func))); 836 convertToBaseCallback(std::move(func)));
809 return true; 837 return true;
810 } 838 }
811 839
812 void Canvas2DLayerBridge::mailboxReleased(const gpu::Mailbox& mailbox, 840 void Canvas2DLayerBridge::mailboxReleased(const gpu::Mailbox& mailbox,
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 Canvas2DLayerBridge::MailboxInfo::MailboxInfo() = default; 1013 Canvas2DLayerBridge::MailboxInfo::MailboxInfo() = default;
986 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) = defaul t; 1014 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) = defaul t;
987 1015
988 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) 1016 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event)
989 { 1017 {
990 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); 1018 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount));
991 hibernationHistogram.count(event); 1019 hibernationHistogram.count(event);
992 } 1020 }
993 1021
994 } // namespace blink 1022 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698