| /* |
| * Copyright (C) 2016 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #pragma once |
| |
| #include "FloatRect.h" |
| #include "GraphicsContext.h" |
| #include <wtf/FastMalloc.h> |
| #include <wtf/Noncopyable.h> |
| #include <wtf/text/WTFString.h> |
| |
| namespace WTF { |
| class TextStream; |
| } |
| |
| namespace WebCore { |
| |
| namespace DisplayList { |
| |
| enum class ItemType : uint8_t { |
| Save, |
| Restore, |
| Translate, |
| Rotate, |
| Scale, |
| ConcatenateCTM, |
| SetCTM, |
| SetState, |
| SetLineCap, |
| SetLineDash, |
| SetLineJoin, |
| SetMiterLimit, |
| ClearShadow, |
| Clip, |
| ClipOut, |
| ClipOutToPath, |
| ClipPath, |
| DrawGlyphs, |
| DrawImage, |
| DrawTiledImage, |
| DrawTiledScaledImage, |
| #if USE(CG) || USE(CAIRO) || USE(DIRECT2D) |
| DrawNativeImage, |
| #endif |
| DrawPattern, |
| DrawRect, |
| DrawLine, |
| DrawLinesForText, |
| DrawDotsForDocumentMarker, |
| DrawEllipse, |
| DrawPath, |
| DrawFocusRingPath, |
| DrawFocusRingRects, |
| FillRect, |
| FillRectWithColor, |
| FillRectWithGradient, |
| FillCompositedRect, |
| FillRoundedRect, |
| FillRectWithRoundedHole, |
| FillPath, |
| FillEllipse, |
| PutImageData, |
| StrokeRect, |
| StrokePath, |
| StrokeEllipse, |
| ClearRect, |
| BeginTransparencyLayer, |
| EndTransparencyLayer, |
| #if USE(CG) |
| ApplyStrokePattern, // FIXME: should not be a recorded item. |
| ApplyFillPattern, // FIXME: should not be a recorded item. |
| #endif |
| ApplyDeviceScaleFactor, |
| }; |
| |
| class Item : public RefCounted<Item> { |
| public: |
| Item() = delete; |
| |
| WEBCORE_EXPORT Item(ItemType); |
| WEBCORE_EXPORT virtual ~Item(); |
| |
| ItemType type() const |
| { |
| return m_type; |
| } |
| |
| virtual void apply(GraphicsContext&) const = 0; |
| |
| static constexpr bool isDisplayListItem = true; |
| |
| virtual bool isDrawingItem() const { return false; } |
| |
| // A state item is one preserved by Save/Restore. |
| bool isStateItem() const |
| { |
| return isStateItemType(m_type); |
| } |
| |
| static bool isStateItemType(ItemType itemType) |
| { |
| switch (itemType) { |
| case ItemType::Translate: |
| case ItemType::Rotate: |
| case ItemType::Scale: |
| case ItemType::ConcatenateCTM: |
| case ItemType::SetCTM: |
| case ItemType::SetState: |
| case ItemType::SetLineCap: |
| case ItemType::SetLineDash: |
| case ItemType::SetLineJoin: |
| case ItemType::SetMiterLimit: |
| case ItemType::ClearShadow: |
| return true; |
| default: |
| return false; |
| } |
| return false; |
| } |
| |
| #if !defined(NDEBUG) || !LOG_DISABLED |
| WTF::CString description() const; |
| #endif |
| static size_t sizeInBytes(const Item&); |
| |
| template<class Encoder> void encode(Encoder&) const; |
| template<class Decoder> static Optional<Ref<Item>> decode(Decoder&); |
| |
| private: |
| ItemType m_type; |
| }; |
| |
| enum AsTextFlag { |
| None = 0, |
| IncludesPlatformOperations = 1 << 0, |
| }; |
| |
| typedef unsigned AsTextFlags; |
| |
| class DisplayList { |
| WTF_MAKE_NONCOPYABLE(DisplayList); WTF_MAKE_FAST_ALLOCATED; |
| friend class Recorder; |
| friend class Replayer; |
| public: |
| DisplayList() = default; |
| DisplayList(DisplayList&&) = default; |
| |
| DisplayList& operator=(DisplayList&&) = default; |
| |
| void dump(WTF::TextStream&) const; |
| |
| const Vector<Ref<Item>>& list() const { return m_list; } |
| Item& itemAt(size_t index) |
| { |
| ASSERT(index < m_list.size()); |
| return m_list[index].get(); |
| } |
| |
| WEBCORE_EXPORT void clear(); |
| |
| size_t itemCount() const { return m_list.size(); } |
| size_t sizeInBytes() const; |
| |
| String asText(AsTextFlags) const; |
| |
| #if !defined(NDEBUG) || !LOG_DISABLED |
| WTF::CString description() const; |
| WEBCORE_EXPORT void dump() const; |
| #endif |
| |
| template<class Encoder> void encode(Encoder&) const; |
| template<class Decoder> static Optional<DisplayList> decode(Decoder&); |
| |
| |
| private: |
| Item& append(Ref<Item>&& item) |
| { |
| m_list.append(WTFMove(item)); |
| return m_list.last().get(); |
| } |
| |
| // Less efficient append, only used for tracking replay. |
| void appendItem(Item& item) |
| { |
| m_list.append(item); |
| } |
| |
| static bool shouldDumpForFlags(AsTextFlags, const Item&); |
| |
| Vector<Ref<Item>>& list() { return m_list; } |
| |
| Vector<Ref<Item>> m_list; |
| }; |
| |
| |
| template<class Encoder> |
| void DisplayList::encode(Encoder& encoder) const |
| { |
| encoder << static_cast<uint64_t>(m_list.size()); |
| |
| for (auto& item : m_list) |
| encoder << item.get(); |
| } |
| |
| template<class Decoder> |
| Optional<DisplayList> DisplayList::decode(Decoder& decoder) |
| { |
| Optional<uint64_t> itemCount; |
| decoder >> itemCount; |
| if (!itemCount) |
| return WTF::nullopt; |
| |
| DisplayList displayList; |
| |
| for (uint64_t i = 0; i < *itemCount; i++) { |
| auto item = Item::decode(decoder); |
| // FIXME: Once we can decode all types, failing to decode an item should turn into a decode failure. |
| // For now, we just have to ignore it. |
| if (!item) |
| continue; |
| displayList.append(WTFMove(*item)); |
| } |
| |
| return displayList; |
| } |
| |
| } // DisplayList |
| |
| WTF::TextStream& operator<<(WTF::TextStream&, const DisplayList::DisplayList&); |
| |
| } // WebCore |