Changeset 195646 in webkit
- Timestamp:
- Jan 26, 2016 5:53:18 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r195642 r195646 1 2016-01-26 Simon Fraser <simon.fraser@apple.com> 2 3 Allow canvas to use display-list drawing for testing 4 https://bugs.webkit.org/show_bug.cgi?id=153475 5 6 Reviewed by Dean Jackson. 7 8 Simple canvas-based display list test. 9 10 * displaylists/canvas-display-list-expected.txt: Added. 11 * displaylists/canvas-display-list.html: Added. 12 1 13 2016-01-26 Chris Dumez <cdumez@apple.com> 2 14 -
trunk/Source/WebCore/ChangeLog
r195644 r195646 1 2016-01-26 Simon Fraser <simon.fraser@apple.com> 2 3 Allow canvas to use display-list drawing for testing 4 https://bugs.webkit.org/show_bug.cgi?id=153475 5 6 Reviewed by Dean Jackson. 7 8 Optionally have 2D <canvas> use display-list drawing, which is only enabled 9 via Internals for now. 10 11 Support displayListAsText() and replayDisplayListAsText() on canvas, so we can 12 use it to test playback optimizations. [Note that displayListAsText() always 13 returns an empty string currently, because the display list is cleared when the 14 canvas is painted to the page.] 15 16 Display list rendering is implemented by giving CanvasRenderingContext2D an 17 optional DisplayListDrawingContext, which packages up a display list, recorder 18 and recording context. The existing paintRenderingResultsToCanvas() is overridden 19 to replay the recorded display list into the primary canvas context. 20 21 Tracked replay display lists are stored in a static map, keyed by the CanvasRenderingContext2D. 22 23 Test: displaylists/canvas-display-list.html 24 25 * html/HTMLCanvasElement.cpp: 26 (WebCore::HTMLCanvasElement::HTMLCanvasElement): 27 (WebCore::HTMLCanvasElement::getContext): 28 (WebCore::HTMLCanvasElement::paint): 29 (WebCore::HTMLCanvasElement::setUsesDisplayListDrawing): 30 (WebCore::HTMLCanvasElement::setTracksDisplayListReplay): 31 (WebCore::HTMLCanvasElement::displayListAsText): 32 (WebCore::HTMLCanvasElement::replayDisplayListAsText): 33 * html/HTMLCanvasElement.h: 34 * html/canvas/CanvasRenderingContext.h: 35 * html/canvas/CanvasRenderingContext2D.cpp: 36 (WebCore::DisplayListDrawingContext::DisplayListDrawingContext): 37 (WebCore::contextDisplayListMap): 38 (WebCore::CanvasRenderingContext2D::~CanvasRenderingContext2D): 39 (WebCore::CanvasRenderingContext2D::setTracksDisplayListReplay): 40 (WebCore::CanvasRenderingContext2D::displayListAsText): 41 (WebCore::CanvasRenderingContext2D::replayDisplayListAsText): 42 (WebCore::CanvasRenderingContext2D::paintRenderingResultsToCanvas): 43 (WebCore::CanvasRenderingContext2D::drawingContext): 44 (WebCore::CanvasRenderingContext2D::CanvasRenderingContext2D): Deleted. 45 * html/canvas/CanvasRenderingContext2D.h: 46 * testing/Internals.cpp: 47 (WebCore::Internals::setElementUsesDisplayListDrawing): 48 (WebCore::Internals::setElementTracksDisplayListReplay): 49 (WebCore::Internals::displayListForElement): 50 (WebCore::Internals::replayDisplayListForElement): 51 1 52 2016-01-26 Joseph Pecoraro <pecoraro@apple.com> 2 53 -
trunk/Source/WebCore/html/HTMLCanvasElement.cpp
r195643 r195646 233 233 234 234 m_context = std::make_unique<CanvasRenderingContext2D>(this, document().inQuirksMode(), usesDashbardCompatibilityMode); 235 236 downcast<CanvasRenderingContext2D>(*m_context).setUsesDisplayListDrawing(m_usesDisplayListDrawing); 237 downcast<CanvasRenderingContext2D>(*m_context).setTracksDisplayListReplay(m_tracksDisplayListReplay); 238 235 239 #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS) 236 240 // Need to make sure a RenderLayer and compositing layer get created for the Canvas … … 411 415 if (!paintsIntoCanvasBuffer() && !document().printing()) 412 416 return; 417 413 418 m_context->paintRenderingResultsToCanvas(); 414 419 } … … 590 595 } 591 596 597 void HTMLCanvasElement::setUsesDisplayListDrawing(bool usesDisplayListDrawing) 598 { 599 if (usesDisplayListDrawing == m_usesDisplayListDrawing) 600 return; 601 602 m_usesDisplayListDrawing = usesDisplayListDrawing; 603 604 if (m_context && is<CanvasRenderingContext2D>(*m_context)) 605 downcast<CanvasRenderingContext2D>(*m_context).setUsesDisplayListDrawing(m_usesDisplayListDrawing); 606 } 607 608 void HTMLCanvasElement::setTracksDisplayListReplay(bool tracksDisplayListReplay) 609 { 610 if (tracksDisplayListReplay == m_tracksDisplayListReplay) 611 return; 612 613 m_tracksDisplayListReplay = tracksDisplayListReplay; 614 615 if (m_context && is<CanvasRenderingContext2D>(*m_context)) 616 downcast<CanvasRenderingContext2D>(*m_context).setTracksDisplayListReplay(m_tracksDisplayListReplay); 617 } 618 619 String HTMLCanvasElement::displayListAsText(DisplayList::AsTextFlags flags) const 620 { 621 if (m_context && is<CanvasRenderingContext2D>(*m_context)) 622 return downcast<CanvasRenderingContext2D>(*m_context).displayListAsText(flags); 623 624 return String(); 625 } 626 627 String HTMLCanvasElement::replayDisplayListAsText(DisplayList::AsTextFlags flags) const 628 { 629 if (m_context && is<CanvasRenderingContext2D>(*m_context)) 630 return downcast<CanvasRenderingContext2D>(*m_context).replayDisplayListAsText(flags); 631 632 return String(); 633 } 634 592 635 void HTMLCanvasElement::createImageBuffer() const 593 636 { -
trunk/Source/WebCore/html/HTMLCanvasElement.h
r195643 r195646 52 52 class ImageBuffer; 53 53 class IntSize; 54 55 namespace DisplayList { 56 typedef unsigned AsTextFlags; 57 } 54 58 55 59 class CanvasObserver { … … 136 140 bool shouldAccelerate(const IntSize&) const; 137 141 142 WEBCORE_EXPORT void setUsesDisplayListDrawing(bool); 143 WEBCORE_EXPORT void setTracksDisplayListReplay(bool); 144 WEBCORE_EXPORT String displayListAsText(DisplayList::AsTextFlags) const; 145 WEBCORE_EXPORT String replayDisplayListAsText(DisplayList::AsTextFlags) const; 146 138 147 size_t memoryCost() const; 139 148 … … 172 181 bool m_ignoreReset { false }; 173 182 183 bool m_usesDisplayListDrawing { false }; 184 bool m_tracksDisplayListReplay { false }; 185 174 186 // m_createdImageBuffer means we tried to malloc the buffer. We didn't necessarily get it. 175 187 mutable bool m_hasCreatedImageBuffer { false }; -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h
r178674 r195646 82 82 } // namespace WebCore 83 83 84 #define SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(ToValueTypeName, predicate) \ 85 SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \ 86 static bool isType(const WebCore::CanvasRenderingContext& context) { return context.predicate; } \ 87 SPECIALIZE_TYPE_TRAITS_END() 88 84 89 #endif -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
r195614 r195646 41 41 #include "CanvasPattern.h" 42 42 #include "DOMPath.h" 43 #include "DisplayListRecorder.h" 44 #include "DisplayListReplayer.h" 43 45 #include "ExceptionCodePlaceholder.h" 44 46 #include "FloatQuad.h" … … 56 58 #include "TextMetrics.h" 57 59 #include "TextRun.h" 60 #include "TextStream.h" 58 61 59 62 #include <wtf/CheckedArithmetic.h> … … 85 88 static const char* const defaultFontFamily = "sans-serif"; 86 89 static const char* const defaultFont = "10px sans-serif"; 90 91 struct DisplayListDrawingContext { 92 GraphicsContext context; 93 DisplayList::Recorder recorder; 94 DisplayList::DisplayList displayList; 95 96 DisplayListDrawingContext(const FloatRect& clip) 97 : recorder(context, displayList, clip, AffineTransform()) 98 { 99 } 100 }; 101 102 typedef HashMap<const CanvasRenderingContext2D*, std::unique_ptr<DisplayList::DisplayList>> ContextDisplayListHashMap; 103 104 static ContextDisplayListHashMap& contextDisplayListMap() 105 { 106 static NeverDestroyed<ContextDisplayListHashMap> sharedHashMap; 107 return sharedHashMap; 108 } 87 109 88 110 class CanvasStrokeStyleApplier : public StrokeStyleApplier { … … 113 135 : CanvasRenderingContext(canvas) 114 136 , m_stateStack(1) 115 , m_unrealizedSaveCount(0)116 137 , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode) 117 138 #if ENABLE(DASHBOARD_SUPPORT) … … 142 163 unwindStateStack(); 143 164 #endif 165 166 if (UNLIKELY(tracksDisplayListReplay())) 167 contextDisplayListMap().remove(this); 144 168 } 145 169 … … 163 187 m_path.clear(); 164 188 m_unrealizedSaveCount = 0; 189 190 m_recordingContext = nullptr; 165 191 } 166 192 … … 1908 1934 } 1909 1935 1936 void CanvasRenderingContext2D::setTracksDisplayListReplay(bool tracksDisplayListReplay) 1937 { 1938 if (tracksDisplayListReplay == m_tracksDisplayListReplay) 1939 return; 1940 1941 m_tracksDisplayListReplay = tracksDisplayListReplay; 1942 if (!m_tracksDisplayListReplay) 1943 contextDisplayListMap().remove(this); 1944 } 1945 1946 String CanvasRenderingContext2D::displayListAsText(DisplayList::AsTextFlags flags) const 1947 { 1948 if (m_recordingContext) 1949 return m_recordingContext->displayList.asText(flags); 1950 1951 return String(); 1952 } 1953 1954 String CanvasRenderingContext2D::replayDisplayListAsText(DisplayList::AsTextFlags flags) const 1955 { 1956 auto it = contextDisplayListMap().find(this); 1957 if (it != contextDisplayListMap().end()) { 1958 TextStream stream; 1959 stream << it->value->asText(flags); 1960 return stream.release(); 1961 } 1962 1963 return String(); 1964 } 1965 1966 void CanvasRenderingContext2D::paintRenderingResultsToCanvas() 1967 { 1968 if (UNLIKELY(m_usesDisplayListDrawing)) { 1969 if (!m_recordingContext) 1970 return; 1971 1972 FloatRect clip(FloatPoint::zero(), canvas()->size()); 1973 DisplayList::Replayer replayer(*canvas()->drawingContext(), m_recordingContext->displayList); 1974 1975 if (UNLIKELY(m_tracksDisplayListReplay)) { 1976 auto replayList = replayer.replay(clip, m_tracksDisplayListReplay); 1977 contextDisplayListMap().add(this, WTFMove(replayList)); 1978 } else 1979 replayer.replay(clip); 1980 1981 m_recordingContext->displayList.clear(); 1982 } 1983 } 1984 1910 1985 GraphicsContext* CanvasRenderingContext2D::drawingContext() const 1911 1986 { 1987 if (UNLIKELY(m_usesDisplayListDrawing)) { 1988 if (!m_recordingContext) 1989 m_recordingContext = std::make_unique<DisplayListDrawingContext>(FloatRect(FloatPoint::zero(), canvas()->size())); 1990 1991 return &m_recordingContext->context; 1992 } 1993 1912 1994 return canvas()->drawingContext(); 1913 1995 } -
trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
r192140 r195646 238 238 }; 239 239 240 bool usesDisplayListDrawing() const { return m_usesDisplayListDrawing; }; 241 void setUsesDisplayListDrawing(bool flag) { m_usesDisplayListDrawing = flag; }; 242 243 bool tracksDisplayListReplay() const { return m_tracksDisplayListReplay; } 244 void setTracksDisplayListReplay(bool); 245 246 String displayListAsText(DisplayList::AsTextFlags) const; 247 String replayDisplayListAsText(DisplayList::AsTextFlags) const; 248 240 249 private: 241 250 enum class Direction { … … 321 330 void didDrawEntireCanvas(); 322 331 332 void paintRenderingResultsToCanvas() override; 333 323 334 GraphicsContext* drawingContext() const; 324 335 … … 385 396 386 397 Vector<State, 1> m_stateStack; 387 unsigned m_unrealizedSaveCount ;398 unsigned m_unrealizedSaveCount { 0 }; 388 399 bool m_usesCSSCompatibilityParseMode; 389 400 #if ENABLE(DASHBOARD_SUPPORT) 390 401 bool m_usesDashboardCompatibilityMode; 391 402 #endif 403 404 bool m_usesDisplayListDrawing { false }; 405 bool m_tracksDisplayListReplay { false }; 406 mutable std::unique_ptr<struct DisplayListDrawingContext> m_recordingContext; 392 407 }; 393 408 394 409 } // namespace WebCore 395 410 411 SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::CanvasRenderingContext2D, is2d()) 412 396 413 #endif -
trunk/Source/WebCore/testing/Internals.cpp
r195515 r195646 58 58 #include "FrameLoader.h" 59 59 #include "FrameView.h" 60 #include "HTMLCanvasElement.h" 60 61 #include "HTMLIFrameElement.h" 61 62 #include "HTMLImageElement.h" … … 1983 1984 } 1984 1985 1985 if (!element || !element->renderer() || !element->renderer()->hasLayer()) { 1986 ec = INVALID_ACCESS_ERR; 1987 return; 1988 } 1989 1990 RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer(); 1991 if (!layer->isComposited()) { 1992 ec = INVALID_ACCESS_ERR; 1993 return; 1994 } 1995 1996 layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing); 1997 } 1998 1999 void Internals::setElementTracksDisplayListReplay(Element* element, bool isTrackingReplay, ExceptionCode& ec) 2000 { 2001 Document* document = contextDocument(); 2002 if (!document || !document->renderView()) { 2003 ec = INVALID_ACCESS_ERR; 2004 return; 2005 } 2006 2007 if (!element || !element->renderer() || !element->renderer()->hasLayer()) { 2008 ec = INVALID_ACCESS_ERR; 2009 return; 2010 } 2011 2012 RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer(); 2013 if (!layer->isComposited()) { 2014 ec = INVALID_ACCESS_ERR; 2015 return; 2016 } 2017 2018 layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay); 2019 } 2020 2021 String Internals::displayListForElement(Element* element, ExceptionCode& ec) 2022 { 2023 return displayListForElement(element, 0, ec); 2024 } 2025 2026 String Internals::displayListForElement(Element* element, unsigned flags, ExceptionCode& ec) 2027 { 2028 Document* document = contextDocument(); 2029 if (!document || !document->renderView()) { 2030 ec = INVALID_ACCESS_ERR; 2031 return String(); 2032 } 2033 2034 if (!element || !element->renderer() || !element->renderer()->hasLayer()) { 2035 ec = INVALID_ACCESS_ERR; 2036 return String(); 1986 if (!element || !element->renderer()) { 1987 ec = INVALID_ACCESS_ERR; 1988 return; 1989 } 1990 1991 if (is<HTMLCanvasElement>(*element)) { 1992 downcast<HTMLCanvasElement>(*element).setUsesDisplayListDrawing(usesDisplayListDrawing); 1993 return; 1994 } 1995 1996 if (!element->renderer()->hasLayer()) { 1997 ec = INVALID_ACCESS_ERR; 1998 return; 2037 1999 } 2038 2000 … … 2040 2002 if (!layer->isComposited()) { 2041 2003 ec = INVALID_ACCESS_ERR; 2004 return; 2005 } 2006 2007 layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing); 2008 } 2009 2010 void Internals::setElementTracksDisplayListReplay(Element* element, bool isTrackingReplay, ExceptionCode& ec) 2011 { 2012 Document* document = contextDocument(); 2013 if (!document || !document->renderView()) { 2014 ec = INVALID_ACCESS_ERR; 2015 return; 2016 } 2017 2018 if (!element || !element->renderer()) { 2019 ec = INVALID_ACCESS_ERR; 2020 return; 2021 } 2022 2023 if (is<HTMLCanvasElement>(*element)) { 2024 downcast<HTMLCanvasElement>(*element).setTracksDisplayListReplay(isTrackingReplay); 2025 return; 2026 } 2027 2028 if (!element->renderer()->hasLayer()) { 2029 ec = INVALID_ACCESS_ERR; 2030 return; 2031 } 2032 2033 RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer(); 2034 if (!layer->isComposited()) { 2035 ec = INVALID_ACCESS_ERR; 2036 return; 2037 } 2038 2039 layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay); 2040 } 2041 2042 String Internals::displayListForElement(Element* element, ExceptionCode& ec) 2043 { 2044 return displayListForElement(element, 0, ec); 2045 } 2046 2047 String Internals::displayListForElement(Element* element, unsigned flags, ExceptionCode& ec) 2048 { 2049 Document* document = contextDocument(); 2050 if (!document || !document->renderView()) { 2051 ec = INVALID_ACCESS_ERR; 2052 return String(); 2053 } 2054 2055 if (!element || !element->renderer()) { 2056 ec = INVALID_ACCESS_ERR; 2042 2057 return String(); 2043 2058 } … … 2046 2061 if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS) 2047 2062 displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations; 2048 2049 return layer->backing()->displayListAsText(displayListFlags); 2050 } 2051 2052 String Internals::replayDisplayListForElement(Element* element, ExceptionCode& ec) 2053 { 2054 return replayDisplayListForElement(element, 0, ec); 2055 } 2056 2057 String Internals::replayDisplayListForElement(Element* element, unsigned flags, ExceptionCode& ec) 2058 { 2059 Document* document = contextDocument(); 2060 if (!document || !document->renderView()) { 2061 ec = INVALID_ACCESS_ERR; 2062 return String(); 2063 } 2064 2065 if (!element || !element->renderer() || !element->renderer()->hasLayer()) { 2066 ec = INVALID_ACCESS_ERR; 2067 return String(); 2068 } 2069 2063 2064 if (is<HTMLCanvasElement>(*element)) 2065 return downcast<HTMLCanvasElement>(*element).displayListAsText(displayListFlags); 2066 2067 if (!element->renderer()->hasLayer()) { 2068 ec = INVALID_ACCESS_ERR; 2069 return String(); 2070 } 2071 2070 2072 RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer(); 2071 2073 if (!layer->isComposited()) { 2074 ec = INVALID_ACCESS_ERR; 2075 return String(); 2076 } 2077 2078 return layer->backing()->displayListAsText(displayListFlags); 2079 } 2080 2081 String Internals::replayDisplayListForElement(Element* element, ExceptionCode& ec) 2082 { 2083 return replayDisplayListForElement(element, 0, ec); 2084 } 2085 2086 String Internals::replayDisplayListForElement(Element* element, unsigned flags, ExceptionCode& ec) 2087 { 2088 Document* document = contextDocument(); 2089 if (!document || !document->renderView()) { 2090 ec = INVALID_ACCESS_ERR; 2091 return String(); 2092 } 2093 2094 if (!element || !element->renderer()) { 2072 2095 ec = INVALID_ACCESS_ERR; 2073 2096 return String(); … … 2077 2100 if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS) 2078 2101 displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations; 2079 2102 2103 if (is<HTMLCanvasElement>(*element)) 2104 return downcast<HTMLCanvasElement>(*element).replayDisplayListAsText(displayListFlags); 2105 2106 if (!element->renderer()->hasLayer()) { 2107 ec = INVALID_ACCESS_ERR; 2108 return String(); 2109 } 2110 2111 RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer(); 2112 if (!layer->isComposited()) { 2113 ec = INVALID_ACCESS_ERR; 2114 return String(); 2115 } 2116 2080 2117 return layer->backing()->replayDisplayListAsText(displayListFlags); 2081 2118 }
Note: See TracChangeset
for help on using the changeset viewer.