Changeset 195646 in webkit


Ignore:
Timestamp:
Jan 26, 2016 5:53:18 PM (8 years ago)
Author:
Simon Fraser
Message:

Allow canvas to use display-list drawing for testing
https://bugs.webkit.org/show_bug.cgi?id=153475

Reviewed by Dean Jackson.

Source/WebCore:

Optionally have 2D <canvas> use display-list drawing, which is only enabled
via Internals for now.

Support displayListAsText() and replayDisplayListAsText() on canvas, so we can
use it to test playback optimizations. [Note that displayListAsText() always
returns an empty string currently, because the display list is cleared when the
canvas is painted to the page.]

Display list rendering is implemented by giving CanvasRenderingContext2D an
optional DisplayListDrawingContext, which packages up a display list, recorder
and recording context. The existing paintRenderingResultsToCanvas() is overridden
to replay the recorded display list into the primary canvas context.

Tracked replay display lists are stored in a static map, keyed by the CanvasRenderingContext2D.

Test: displaylists/canvas-display-list.html

  • html/HTMLCanvasElement.cpp:

(WebCore::HTMLCanvasElement::HTMLCanvasElement):
(WebCore::HTMLCanvasElement::getContext):
(WebCore::HTMLCanvasElement::paint):
(WebCore::HTMLCanvasElement::setUsesDisplayListDrawing):
(WebCore::HTMLCanvasElement::setTracksDisplayListReplay):
(WebCore::HTMLCanvasElement::displayListAsText):
(WebCore::HTMLCanvasElement::replayDisplayListAsText):

  • html/HTMLCanvasElement.h:
  • html/canvas/CanvasRenderingContext.h:
  • html/canvas/CanvasRenderingContext2D.cpp:

(WebCore::DisplayListDrawingContext::DisplayListDrawingContext):
(WebCore::contextDisplayListMap):
(WebCore::CanvasRenderingContext2D::~CanvasRenderingContext2D):
(WebCore::CanvasRenderingContext2D::setTracksDisplayListReplay):
(WebCore::CanvasRenderingContext2D::displayListAsText):
(WebCore::CanvasRenderingContext2D::replayDisplayListAsText):
(WebCore::CanvasRenderingContext2D::paintRenderingResultsToCanvas):
(WebCore::CanvasRenderingContext2D::drawingContext):
(WebCore::CanvasRenderingContext2D::CanvasRenderingContext2D): Deleted.

  • html/canvas/CanvasRenderingContext2D.h:
  • testing/Internals.cpp:

(WebCore::Internals::setElementUsesDisplayListDrawing):
(WebCore::Internals::setElementTracksDisplayListReplay):
(WebCore::Internals::displayListForElement):
(WebCore::Internals::replayDisplayListForElement):

LayoutTests:

Simple canvas-based display list test.

  • displaylists/canvas-display-list-expected.txt: Added.
  • displaylists/canvas-display-list.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195642 r195646  
     12016-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
    1132016-01-26  Chris Dumez  <cdumez@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r195644 r195646  
     12016-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
    1522016-01-26  Joseph Pecoraro  <pecoraro@apple.com>
    253
  • trunk/Source/WebCore/html/HTMLCanvasElement.cpp

    r195643 r195646  
    233233
    234234            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
    235239#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
    236240            // Need to make sure a RenderLayer and compositing layer get created for the Canvas
     
    411415        if (!paintsIntoCanvasBuffer() && !document().printing())
    412416            return;
     417
    413418        m_context->paintRenderingResultsToCanvas();
    414419    }
     
    590595}
    591596
     597void 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
     608void 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
     619String 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
     627String 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
    592635void HTMLCanvasElement::createImageBuffer() const
    593636{
  • trunk/Source/WebCore/html/HTMLCanvasElement.h

    r195643 r195646  
    5252class ImageBuffer;
    5353class IntSize;
     54
     55namespace DisplayList {
     56typedef unsigned AsTextFlags;
     57}
    5458
    5559class CanvasObserver {
     
    136140    bool shouldAccelerate(const IntSize&) const;
    137141
     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
    138147    size_t memoryCost() const;
    139148
     
    172181    bool m_ignoreReset { false };
    173182
     183    bool m_usesDisplayListDrawing { false };
     184    bool m_tracksDisplayListReplay { false };
     185
    174186    // m_createdImageBuffer means we tried to malloc the buffer.  We didn't necessarily get it.
    175187    mutable bool m_hasCreatedImageBuffer { false };
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h

    r178674 r195646  
    8282} // namespace WebCore
    8383
     84#define SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(ToValueTypeName, predicate) \
     85SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
     86    static bool isType(const WebCore::CanvasRenderingContext& context) { return context.predicate; } \
     87SPECIALIZE_TYPE_TRAITS_END()
     88
    8489#endif
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r195614 r195646  
    4141#include "CanvasPattern.h"
    4242#include "DOMPath.h"
     43#include "DisplayListRecorder.h"
     44#include "DisplayListReplayer.h"
    4345#include "ExceptionCodePlaceholder.h"
    4446#include "FloatQuad.h"
     
    5658#include "TextMetrics.h"
    5759#include "TextRun.h"
     60#include "TextStream.h"
    5861
    5962#include <wtf/CheckedArithmetic.h>
     
    8588static const char* const defaultFontFamily = "sans-serif";
    8689static const char* const defaultFont = "10px sans-serif";
     90
     91struct 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
     102typedef HashMap<const CanvasRenderingContext2D*, std::unique_ptr<DisplayList::DisplayList>> ContextDisplayListHashMap;
     103
     104static ContextDisplayListHashMap& contextDisplayListMap()
     105{
     106    static NeverDestroyed<ContextDisplayListHashMap> sharedHashMap;
     107    return sharedHashMap;
     108}
    87109
    88110class CanvasStrokeStyleApplier : public StrokeStyleApplier {
     
    113135    : CanvasRenderingContext(canvas)
    114136    , m_stateStack(1)
    115     , m_unrealizedSaveCount(0)
    116137    , m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode)
    117138#if ENABLE(DASHBOARD_SUPPORT)
     
    142163    unwindStateStack();
    143164#endif
     165
     166    if (UNLIKELY(tracksDisplayListReplay()))
     167        contextDisplayListMap().remove(this);
    144168}
    145169
     
    163187    m_path.clear();
    164188    m_unrealizedSaveCount = 0;
     189   
     190    m_recordingContext = nullptr;
    165191}
    166192
     
    19081934}
    19091935
     1936void 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
     1946String CanvasRenderingContext2D::displayListAsText(DisplayList::AsTextFlags flags) const
     1947{
     1948    if (m_recordingContext)
     1949        return m_recordingContext->displayList.asText(flags);
     1950   
     1951    return String();
     1952}
     1953
     1954String 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
     1966void 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
    19101985GraphicsContext* CanvasRenderingContext2D::drawingContext() const
    19111986{
     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
    19121994    return canvas()->drawingContext();
    19131995}
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h

    r192140 r195646  
    238238    };
    239239
     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
    240249private:
    241250    enum class Direction {
     
    321330    void didDrawEntireCanvas();
    322331
     332    void paintRenderingResultsToCanvas() override;
     333
    323334    GraphicsContext* drawingContext() const;
    324335
     
    385396
    386397    Vector<State, 1> m_stateStack;
    387     unsigned m_unrealizedSaveCount;
     398    unsigned m_unrealizedSaveCount { 0 };
    388399    bool m_usesCSSCompatibilityParseMode;
    389400#if ENABLE(DASHBOARD_SUPPORT)
    390401    bool m_usesDashboardCompatibilityMode;
    391402#endif
     403
     404    bool m_usesDisplayListDrawing { false };
     405    bool m_tracksDisplayListReplay { false };
     406    mutable std::unique_ptr<struct DisplayListDrawingContext> m_recordingContext;
    392407};
    393408
    394409} // namespace WebCore
    395410
     411SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::CanvasRenderingContext2D, is2d())
     412
    396413#endif
  • trunk/Source/WebCore/testing/Internals.cpp

    r195515 r195646  
    5858#include "FrameLoader.h"
    5959#include "FrameView.h"
     60#include "HTMLCanvasElement.h"
    6061#include "HTMLIFrameElement.h"
    6162#include "HTMLImageElement.h"
     
    19831984    }
    19841985
    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;
    20371999    }
    20382000   
     
    20402002    if (!layer->isComposited()) {
    20412003        ec = INVALID_ACCESS_ERR;
     2004        return;
     2005    }
     2006   
     2007    layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
     2008}
     2009
     2010void 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
     2042String Internals::displayListForElement(Element* element, ExceptionCode& ec)
     2043{
     2044    return displayListForElement(element, 0, ec);
     2045}
     2046
     2047String 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;
    20422057        return String();
    20432058    }
     
    20462061    if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
    20472062        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
    20702072    RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
    20712073    if (!layer->isComposited()) {
     2074        ec = INVALID_ACCESS_ERR;
     2075        return String();
     2076    }
     2077
     2078    return layer->backing()->displayListAsText(displayListFlags);
     2079}
     2080
     2081String Internals::replayDisplayListForElement(Element* element, ExceptionCode& ec)
     2082{
     2083    return replayDisplayListForElement(element, 0, ec);
     2084}
     2085
     2086String 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()) {
    20722095        ec = INVALID_ACCESS_ERR;
    20732096        return String();
     
    20772100    if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
    20782101        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
    20802117    return layer->backing()->replayDisplayListAsText(displayListFlags);
    20812118}
Note: See TracChangeset for help on using the changeset viewer.