// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef DisplayItem_h
#define DisplayItem_h

#include "platform/PlatformExport.h"
#include "platform/graphics/ContiguousContainer.h"
#include "platform/graphics/paint/DisplayItemClient.h"
#include "wtf/Allocator.h"
#include "wtf/Assertions.h"
#include "wtf/Noncopyable.h"

#ifndef NDEBUG
#include "wtf/text/StringBuilder.h"
#include "wtf/text/WTFString.h"
#endif

class SkPictureGpuAnalyzer;

namespace blink {

class GraphicsContext;
class IntRect;
class WebDisplayItemList;

class PLATFORM_EXPORT DisplayItem {
  DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

 public:
  enum {
    // Must be kept in sync with core/paint/PaintPhase.h.
    kPaintPhaseMax = 11,
  };

  // A display item type uniquely identifies a display item of a client.
  // Some display item types can be categorized using the following directives:
  // - In enum Type:
  //   - enum value <Category>First;
  //   - enum values of the category, first of which should equal
  //     <Category>First (for ease of maintenance, the values should be in
  //     alphabetic order);
  //   - enum value <Category>Last which should be equal to the last of the enum
  //     values of the category
  // - DEFINE_CATEGORY_METHODS(<Category>) to define is<Category>Type(Type) and
  //   is<Category>() methods.
  //
  // A category or subset of a category can contain types each of which
  // corresponds to a PaintPhase:
  // - In enum Type:
  //   - enum value <Category>[<Subset>]PaintPhaseFirst;
  //   - enum value <Category>[<Subset>]PaintPhaseLast =
  //     <Category>[<Subset>]PaintPhaseFirst + PaintPhaseMax;
  // - DEFINE_PAINT_PHASE_CONVERSION_METHOD(<Category>[<Subset>]) to define
  //   paintPhaseTo<Category>[<Subset>]Type(PaintPhase) method.
  //
  // A category can be derived from another category, containing types each of
  // which corresponds to a value of the latter category:
  // - In enum Type:
  //   - enum value <Category>First;
  //   - enum value <Category>Last =
  //     <Category>First + <BaseCategory>Last - <BaseCategory>First;
  // - DEFINE_CONVERSION_METHODS(<Category>,
  //                             <category>,
  //                             <BaseCategory>,
  //                             <baseCategory>)
  //   to define methods to convert types between the categories.
  enum Type {
    kDrawingFirst,
    kDrawingPaintPhaseFirst = kDrawingFirst,
    kDrawingPaintPhaseLast = kDrawingFirst + kPaintPhaseMax,
    kBoxDecorationBackground,
    kCaret,
    kColumnRules,
    kDebugDrawing,
    kDocumentBackground,
    kDragImage,
    kDragCaret,
    kSVGImage,
    kLinkHighlight,
    kImageAreaFocusRing,
    kPageOverlay,
    kPageWidgetDelegateBackgroundFallback,
    kPopupContainerBorder,
    kPopupListBoxBackground,
    kPopupListBoxRow,
    kPrintedContentBackground,
    kPrintedContentDestinationLocations,
    kPrintedContentLineBoundary,
    kPrintedContentPDFURLRect,
    kResizer,
    kSVGClip,
    kSVGFilter,
    kSVGMask,
    kScrollbarBackButtonEnd,
    kScrollbarBackButtonStart,
    kScrollbarBackground,
    kScrollbarBackTrack,
    kScrollbarCorner,
    kScrollbarForwardButtonEnd,
    kScrollbarForwardButtonStart,
    kScrollbarForwardTrack,
    kScrollbarThumb,
    kScrollbarTickmarks,
    kScrollbarTrackBackground,
    kScrollbarCompositedScrollbar,
    kSelectionTint,
    kTableCellBackgroundFromColumnGroup,
    kTableCellBackgroundFromColumn,
    kTableCellBackgroundFromSection,
    kTableCellBackgroundFromRow,
    // Table collapsed borders can be painted together (e.g., left & top) but
    // there are at most 4 phases of collapsed border painting for a single
    // cell. To disambiguate these phases of collapsed border painting, a mask
    // is used. TableCollapsedBorderBase can be larger than
    // TableCollapsedBorderUnalignedBase to ensure the base lower bits are 0's.
    kTableCollapsedBorderUnalignedBase,
    kTableCollapsedBorderBase =
        (((kTableCollapsedBorderUnalignedBase - 1) >> 4) + 1) << 4,
    kTableCollapsedBorderLast = kTableCollapsedBorderBase + 0x0f,
    kTableSectionBoxShadowInset,
    kTableSectionBoxShadowNormal,
    kTableRowBoxShadowInset,
    kTableRowBoxShadowNormal,
    kVideoBitmap,
    kWebPlugin,
    kWebFont,
    kReflectionMask,
    kDrawingLast = kReflectionMask,

    kForeignLayerFirst,
    kForeignLayerCanvas = kForeignLayerFirst,
    kForeignLayerPlugin,
    kForeignLayerVideo,
    kForeignLayerLast = kForeignLayerVideo,

    kClipFirst,
    kClipBoxPaintPhaseFirst = kClipFirst,
    kClipBoxPaintPhaseLast = kClipBoxPaintPhaseFirst + kPaintPhaseMax,
    kClipColumnBoundsPaintPhaseFirst,
    kClipColumnBoundsPaintPhaseLast =
        kClipColumnBoundsPaintPhaseFirst + kPaintPhaseMax,
    kClipLayerFragmentPaintPhaseFirst,
    kClipLayerFragmentPaintPhaseLast =
        kClipLayerFragmentPaintPhaseFirst + kPaintPhaseMax,
    kClipFileUploadControlRect,
    kClipFrameToVisibleContentRect,
    kClipFrameScrollbars,
    kClipLayerBackground,
    kClipLayerColumnBounds,
    kClipLayerFilter,
    kClipLayerForeground,
    kClipLayerParent,
    kClipLayerOverflowControls,
    kClipNodeImage,
    kClipPopupListBoxFrame,
    kClipScrollbarsToBoxBounds,
    kClipSelectionImage,
    kPageWidgetDelegateClip,
    kClipPrintedPage,
    kClipLast = kClipPrintedPage,

    kEndClipFirst,
    kEndClipLast = kEndClipFirst + kClipLast - kClipFirst,

    kFloatClipFirst,
    kFloatClipPaintPhaseFirst = kFloatClipFirst,
    kFloatClipPaintPhaseLast = kFloatClipFirst + kPaintPhaseMax,
    kFloatClipLast = kFloatClipPaintPhaseLast,
    kEndFloatClipFirst,
    kEndFloatClipLast = kEndFloatClipFirst + kFloatClipLast - kFloatClipFirst,

    kScrollFirst,
    kScrollPaintPhaseFirst = kScrollFirst,
    kScrollPaintPhaseLast = kScrollPaintPhaseFirst + kPaintPhaseMax,
    kScrollOverflowControls,
    kScrollLast = kScrollOverflowControls,
    kEndScrollFirst,
    kEndScrollLast = kEndScrollFirst + kScrollLast - kScrollFirst,

    kTransform3DFirst,
    kTransform3DElementTransform = kTransform3DFirst,
    kTransform3DLast = kTransform3DElementTransform,
    kEndTransform3DFirst,
    kEndTransform3DLast =
        kEndTransform3DFirst + kTransform3DLast - kTransform3DFirst,

    kBeginFilter,
    kEndFilter,
    kBeginCompositing,
    kEndCompositing,
    kBeginTransform,
    kEndTransform,
    kBeginClipPath,
    kEndClipPath,

    kSubsequence,
    kEndSubsequence,

    kUninitializedType,
    kTypeLast = kUninitializedType
  };

  static_assert(kTableCollapsedBorderBase >= kTableCollapsedBorderUnalignedBase,
                "TableCollapsedBorder types overlap with other types");
  static_assert((kTableCollapsedBorderBase & 0xf) == 0,
                "The lowest 4 bits of TableCollapsedBorderBase should be zero");
  // Bits or'ed onto TableCollapsedBorderBase to generate a real table collapsed
  // border type.
  enum TableCollapsedBorderSides {
    TableCollapsedBorderTop = 1 << 0,
    TableCollapsedBorderRight = 1 << 1,
    TableCollapsedBorderBottom = 1 << 2,
    TableCollapsedBorderLeft = 1 << 3,
  };

  DisplayItem(const DisplayItemClient& client, Type type, size_t derivedSize)
      : m_client(&client),
        m_type(type),
        m_derivedSize(derivedSize),
        m_skippedCache(false)
#ifndef NDEBUG
        ,
        m_clientDebugString(client.debugName())
#endif
  {
    // derivedSize must fit in m_derivedSize.
    // If it doesn't, enlarge m_derivedSize and fix this assert.
    ASSERT_WITH_SECURITY_IMPLICATION(derivedSize < (1 << 8));
    ASSERT_WITH_SECURITY_IMPLICATION(derivedSize >= sizeof(*this));
  }

  virtual ~DisplayItem() {}

  // Ids are for matching new DisplayItems with existing DisplayItems.
  struct Id {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
    Id(const DisplayItemClient& client, const Type type)
        : client(client), type(type) {}

    const DisplayItemClient& client;
    const Type type;
  };

  Id getId() const { return Id(*m_client, m_type); }

  virtual void replay(GraphicsContext&) const {}

  const DisplayItemClient& client() const {
    ASSERT(m_client);
    return *m_client;
  }
  Type getType() const { return m_type; }

  // Size of this object in memory, used to move it with memcpy.
  // This is not sizeof(*this), because it needs to account for the size of
  // the derived class (i.e. runtime type). Derived classes are expected to
  // supply this to the DisplayItem constructor.
  size_t derivedSize() const { return m_derivedSize; }

  // For PaintController only. Painters should use DisplayItemCacheSkipper
  // instead.
  void setSkippedCache() { m_skippedCache = true; }
  bool skippedCache() const { return m_skippedCache; }

  // TODO(wkorman): Only DrawingDisplayItem needs the visual rect argument.
  // Consider refactoring class hierarchy to make this more explicit.
  virtual void appendToWebDisplayItemList(const IntRect&,
                                          WebDisplayItemList*) const {}

// See comments of enum Type for usage of the following macros.
#define DEFINE_CATEGORY_METHODS(Category)                           \
  static bool is##Category##Type(Type type) {                       \
    return type >= k##Category##First && type <= k##Category##Last; \
  }                                                                 \
  bool is##Category() const { return is##Category##Type(getType()); }

#define DEFINE_CONVERSION_METHODS(Category1, category1, Category2, category2) \
  static Type category1##TypeTo##Category2##Type(Type type) {                 \
    static_assert(k##Category1##Last - k##Category1##First ==                 \
                      k##Category2##Last - k##Category2##First,               \
                  "Categories " #Category1 " and " #Category2                 \
                  " should have same number of enum values. See comments of " \
                  "DisplayItem::Type");                                       \
    ASSERT(is##Category1##Type(type));                                        \
    return static_cast<Type>(type - k##Category1##First +                     \
                             k##Category2##First);                            \
  }                                                                           \
  static Type category2##TypeTo##Category1##Type(Type type) {                 \
    ASSERT(is##Category2##Type(type));                                        \
    return static_cast<Type>(type - k##Category2##First +                     \
                             k##Category1##First);                            \
  }

#define DEFINE_PAIRED_CATEGORY_METHODS(Category, category) \
  DEFINE_CATEGORY_METHODS(Category)                        \
  DEFINE_CATEGORY_METHODS(End##Category)                   \
  DEFINE_CONVERSION_METHODS(Category, category, End##Category, end##Category)

#define DEFINE_PAINT_PHASE_CONVERSION_METHOD(Category)                   \
  static Type paintPhaseTo##Category##Type(int paintPhase) {             \
    static_assert(                                                       \
        k##Category##PaintPhaseLast - k##Category##PaintPhaseFirst ==    \
            k##PaintPhaseMax,                                            \
        "Invalid paint-phase-based category " #Category                  \
        ". See comments of DisplayItem::Type");                          \
    return static_cast<Type>(paintPhase + k##Category##PaintPhaseFirst); \
  }

  DEFINE_CATEGORY_METHODS(Drawing)
  DEFINE_PAINT_PHASE_CONVERSION_METHOD(Drawing)

  DEFINE_CATEGORY_METHODS(ForeignLayer)

  DEFINE_PAIRED_CATEGORY_METHODS(Clip, clip)
  DEFINE_PAINT_PHASE_CONVERSION_METHOD(ClipLayerFragment)
  DEFINE_PAINT_PHASE_CONVERSION_METHOD(ClipBox)
  DEFINE_PAINT_PHASE_CONVERSION_METHOD(ClipColumnBounds)

  DEFINE_PAIRED_CATEGORY_METHODS(FloatClip, floatClip)
  DEFINE_PAINT_PHASE_CONVERSION_METHOD(FloatClip)

  DEFINE_PAIRED_CATEGORY_METHODS(Scroll, scroll)
  DEFINE_PAINT_PHASE_CONVERSION_METHOD(Scroll)

  DEFINE_PAIRED_CATEGORY_METHODS(Transform3D, transform3D)

  static bool isCacheableType(Type type) {
    return isDrawingType(type) || type == kSubsequence;
  }
  bool isCacheable() const {
    return !skippedCache() && isCacheableType(m_type);
  }

  virtual bool isBegin() const { return false; }
  virtual bool isEnd() const { return false; }

#if DCHECK_IS_ON()
  virtual bool isEndAndPairedWith(DisplayItem::Type otherType) const {
    return false;
  }
#endif

  virtual bool equals(const DisplayItem& other) const {
    return m_client == other.m_client && m_type == other.m_type &&
           m_derivedSize == other.m_derivedSize &&
           m_skippedCache == other.m_skippedCache;
  }

  // True if the client is non-null. Because m_client is const, this should
  // never be false except when we explicitly create a tombstone/"dead display
  // item" as part of moving an item from one list to another (see:
  // DisplayItemList::appendByMoving).
  bool hasValidClient() const { return m_client; }

  virtual bool drawsContent() const { return false; }

  // Override to implement specific analysis strategies.
  virtual void analyzeForGpuRasterization(SkPictureGpuAnalyzer&) const {}

#ifndef NDEBUG
  static WTF::String typeAsDebugString(DisplayItem::Type);
  const WTF::String clientDebugString() const { return m_clientDebugString; }
  void setClientDebugString(const WTF::String& s) { m_clientDebugString = s; }
  WTF::String asDebugString() const;
  virtual void dumpPropertiesAsDebugString(WTF::StringBuilder&) const;
#endif

 private:
  // The default DisplayItem constructor is only used by
  // ContiguousContainer::appendByMoving where an invalid DisplaItem is
  // constructed at the source location.
  template <typename T, unsigned alignment>
  friend class ContiguousContainer;

  DisplayItem()
      : m_client(nullptr),
        m_type(kUninitializedType),
        m_derivedSize(sizeof(*this)),
        m_skippedCache(false) {}

  const DisplayItemClient* m_client;
  static_assert(kTypeLast < (1 << 16),
                "DisplayItem::Type should fit in 16 bits");
  const Type m_type : 16;
  const unsigned m_derivedSize : 8;  // size of the actual derived class
  unsigned m_skippedCache : 1;

#ifndef NDEBUG
  WTF::String m_clientDebugString;
#endif
};

inline bool operator==(const DisplayItem::Id& a, const DisplayItem::Id& b) {
  return a.client == b.client && a.type == b.type;
}

inline bool operator!=(const DisplayItem::Id& a, const DisplayItem::Id& b) {
  return !(a == b);
}

class PLATFORM_EXPORT PairedBeginDisplayItem : public DisplayItem {
 protected:
  PairedBeginDisplayItem(const DisplayItemClient& client,
                         Type type,
                         size_t derivedSize)
      : DisplayItem(client, type, derivedSize) {}

 private:
  bool isBegin() const final { return true; }
};

class PLATFORM_EXPORT PairedEndDisplayItem : public DisplayItem {
 protected:
  PairedEndDisplayItem(const DisplayItemClient& client,
                       Type type,
                       size_t derivedSize)
      : DisplayItem(client, type, derivedSize) {}

#if ENABLE(ASSERT)
  bool isEndAndPairedWith(DisplayItem::Type otherType) const override = 0;
#endif

 private:
  bool isEnd() const final { return true; }
};

}  // namespace blink

#endif  // DisplayItem_h
