Changeset 283489 in webkit
- Timestamp:
- Oct 4, 2021, 12:48:10 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
-
ChangeLog (modified) (1 diff)
-
Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp (modified) (3 diffs)
-
Modules/mediastream/CanvasCaptureMediaStreamTrack.h (modified) (4 diffs)
-
html/CanvasBase.cpp (modified) (1 diff)
-
html/CanvasBase.h (modified) (4 diffs)
-
html/HTMLCanvasElement.cpp (modified) (1 diff)
-
html/canvas/WebGLRenderingContextBase.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r283488 r283489 1 2021-10-04 Kimmo Kinnunen <kkinnunen@apple.com> 2 3 Regression (r283238)[ MacOS wk1 ] fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html is timing out 4 https://bugs.webkit.org/show_bug.cgi?id=231022 5 6 Reviewed by Youenn Fablet. 7 8 Originally the implementation would always return red frame, and the test would pass. 9 r283238 changed the implementation to not return a sample if there is not a display buffer, 10 as logically such cannot be used as a sample. 11 This broke the test case since the CanvasCaptureMediaStreamTrack would try to capture 12 the canvas display buffer during next runloop iteration (0s timeout) after each modification. 13 This does not work, as the display buffer is composed during "prepare for display" 14 phase. 15 16 Add CanvasBase observers to observe that display buffer has been prepared, and capture 17 the media sample after that observer has fired. 18 19 The test would work for wk2 due to timing related differences, preparation would have 20 typically run before the canvas capture 0s timeout. 21 22 Fixes fast/mediastream/captureStream/canvas3d.html for wk1. 23 24 * Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp: 25 (WebCore::CanvasCaptureMediaStreamTrack::Source::startProducingData): 26 (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasChanged): 27 (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasDisplayBufferPrepared): 28 * Modules/mediastream/CanvasCaptureMediaStreamTrack.h: 29 * html/CanvasBase.cpp: 30 (WebCore::CanvasBase::addDisplayBufferObserver): 31 (WebCore::CanvasBase::removeDisplayBufferObserver): 32 (WebCore::CanvasBase::notifyObserversCanvasDisplayBufferPrepared): 33 * html/CanvasBase.h: 34 (WebCore::CanvasBase::hasDisplayBufferObservers const): 35 * html/canvas/WebGLRenderingContextBase.cpp: 36 (WebCore::WebGLRenderingContextBase::prepareForDisplay): 37 Move the "prepare only when the owner element is in the tree" logic to 38 its correct place to the caller, e.g. to the element itself. 39 1 40 2021-10-03 Antti Koivisto <antti@apple.com> 2 41 -
trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp
r283238 r283489 90 90 return; 91 91 m_canvas->addObserver(*this); 92 m_canvas->addDisplayBufferObserver(*this); 92 93 93 94 if (!m_frameRequestRate) … … 105 106 return; 106 107 m_canvas->removeObserver(*this); 108 m_canvas->removeDisplayBufferObserver(*this); 107 109 } 108 110 … … 153 155 { 154 156 ASSERT_UNUSED(canvas, m_canvas == &canvas); 155 157 if (m_canvas->renderingContext() && m_canvas->renderingContext()->needsPreparationForDisplay()) 158 return; 159 scheduleCaptureCanvas(); 160 } 161 162 void CanvasCaptureMediaStreamTrack::Source::scheduleCaptureCanvas() 163 { 156 164 // FIXME: We should try to generate the frame at the time the screen is being updated. 157 165 if (m_captureCanvasTimer.isActive()) 158 166 return; 159 167 m_captureCanvasTimer.startOneShot(0_s); 168 } 169 170 void CanvasCaptureMediaStreamTrack::Source::canvasDisplayBufferPrepared(CanvasBase& canvas) 171 { 172 ASSERT_UNUSED(canvas, m_canvas == &canvas); 173 // FIXME: Here we should capture the image instead. 174 // However, submitting the sample to the receiver might cause layout, 175 // and currently the display preparation is done after layout. 176 scheduleCaptureCanvas(); 160 177 } 161 178 -
trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.h
r278253 r283489 31 31 #include "Timer.h" 32 32 #include <wtf/TypeCasts.h> 33 #include <wtf/WeakPtr.h> 33 34 34 35 namespace WebCore { … … 51 52 const char* activeDOMObjectName() const override; 52 53 53 class Source final : public RealtimeMediaSource, private CanvasObserver {54 class Source final : public RealtimeMediaSource, private CanvasObserver, private CanvasDisplayBufferObserver { 54 55 public: 55 56 static Ref<Source> create(HTMLCanvasElement&, std::optional<double>&& frameRequestRate); … … 61 62 Source(HTMLCanvasElement&, std::optional<double>&&); 62 63 63 // CanvasObserver API64 // CanvasObserver overrides. 64 65 void canvasChanged(CanvasBase&, const std::optional<FloatRect>&) final; 65 66 void canvasResized(CanvasBase&) final; 66 67 void canvasDestroyed(CanvasBase&) final; 67 68 68 // RealtimeMediaSource API 69 // CanvasDisplayBufferObserver overrides. 70 void canvasDisplayBufferPrepared(CanvasBase&) final; 71 72 // RealtimeMediaSource overrides. 69 73 void startProducingData() final; 70 74 void stopProducingData() final; … … 72 76 const RealtimeMediaSourceSettings& settings() final; 73 77 void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final; 74 78 void scheduleCaptureCanvas(); 75 79 void captureCanvas(); 76 80 void requestFrameTimerFired(); -
trunk/Source/WebCore/html/CanvasBase.cpp
r278253 r283489 163 163 } 164 164 165 void CanvasBase::addDisplayBufferObserver(CanvasDisplayBufferObserver& observer) 166 { 167 m_displayBufferObservers.add(&observer); 168 } 169 170 void CanvasBase::removeDisplayBufferObserver(CanvasDisplayBufferObserver& observer) 171 { 172 m_displayBufferObservers.remove(observer); 173 } 174 175 void CanvasBase::notifyObserversCanvasDisplayBufferPrepared() 176 { 177 for (auto& observer : m_displayBufferObservers) 178 observer.canvasDisplayBufferPrepared(*this); 179 } 180 165 181 HashSet<Element*> CanvasBase::cssCanvasClients() const 166 182 { -
trunk/Source/WebCore/html/CanvasBase.h
r278253 r283489 29 29 #include <wtf/HashSet.h> 30 30 #include <wtf/TypeCasts.h> 31 #include <wtf/WeakHashSet.h> 31 32 32 33 namespace WebCore { … … 53 54 virtual void canvasResized(CanvasBase&) = 0; 54 55 virtual void canvasDestroyed(CanvasBase&) = 0; 56 }; 57 58 class CanvasDisplayBufferObserver : public CanMakeWeakPtr<CanvasDisplayBufferObserver> { 59 public: 60 virtual ~CanvasDisplayBufferObserver() = default; 61 62 virtual void canvasDisplayBufferPrepared(CanvasBase&) = 0; 55 63 }; 56 64 … … 93 101 void notifyObserversCanvasResized(); 94 102 void notifyObserversCanvasDestroyed(); // Must be called in destruction before clearing m_context. 103 void addDisplayBufferObserver(CanvasDisplayBufferObserver&); 104 void removeDisplayBufferObserver(CanvasDisplayBufferObserver&); 105 void notifyObserversCanvasDisplayBufferPrepared(); 106 bool hasDisplayBufferObservers() const { return !m_displayBufferObservers.computesEmpty(); } 95 107 96 108 HashSet<Element*> cssCanvasClients() const; … … 133 145 #endif 134 146 HashSet<CanvasObserver*> m_observers; 147 WeakHashSet<CanvasDisplayBufferObserver> m_displayBufferObservers; 135 148 }; 136 149 -
trunk/Source/WebCore/html/HTMLCanvasElement.cpp
r283238 r283489 1055 1055 ASSERT(needsPreparationForDisplay()); 1056 1056 1057 bool shouldPrepare = true; 1058 #if ENABLE(WEBGL) 1059 // FIXME: Currently the below prepare skip logic is conservative and applies only to 1060 // WebGL elements. 1061 if (is<WebGLRenderingContextBase>(m_context)) { 1062 // If the canvas is not in the document body, then it won't be 1063 // composited and thus doesn't need preparation. Unfortunately 1064 // it can't tell at the time it was added to the list, since it 1065 // could be inserted or removed from the document body afterwards. 1066 shouldPrepare = isInTreeScope() || hasDisplayBufferObservers(); 1067 } 1068 #endif 1069 if (!shouldPrepare) 1070 return; 1057 1071 if (m_context) 1058 1072 m_context->prepareForDisplay(); 1073 notifyObserversCanvasDisplayBufferPrepared(); 1059 1074 } 1060 1075 -
trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
r283238 r283489 8176 8176 return; 8177 8177 8178 // If the canvas is not in the document body, then it won't be8179 // composited and thus doesn't need preparation. Unfortunately8180 // it can't tell at the time it was added to the list, since it8181 // could be inserted or removed from the document body afterwards.8182 auto canvas = htmlCanvas();8183 if (!canvas || !canvas->isInTreeScope())8184 return;8185 8186 8178 m_context->prepareForDisplay(); 8187 8179 }
Note:
See TracChangeset
for help on using the changeset viewer.