/*
 * Copyright (C) 2009 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 COMPUTER, 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.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_PAINT_LAYER_COMPOSITOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_PAINT_LAYER_COMPOSITOR_H_

#include <memory>
#include "base/gtest_prod_util.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"

namespace blink {

class PaintLayer;
class GraphicsLayer;
class IntPoint;
class JSONObject;
class LayoutEmbeddedContent;
class Page;
class Scrollbar;
class ScrollingCoordinator;
class VisualViewport;

enum CompositingUpdateType {
  kCompositingUpdateNone,
  kCompositingUpdateAfterGeometryChange,
  kCompositingUpdateAfterCompositingInputChange,
  kCompositingUpdateRebuildTree,
};

enum CompositingStateTransitionType {
  kNoCompositingStateChange,
  kAllocateOwnCompositedLayerMapping,
  kRemoveOwnCompositedLayerMapping,
  kPutInSquashingLayer,
  kRemoveFromSquashingLayer
};

// PaintLayerCompositor maintains document-level compositing state and is the
// entry point of the "compositing update" lifecycle stage.  There is one PLC
// per LayoutView.
//
// The compositing update, implemented by PaintLayerCompositor and friends,
// decides for each PaintLayer whether it should get a CompositedLayerMapping,
// and asks each CLM to set up its GraphicsLayers.
//
// When root layer scrolling is disabled, PaintLayerCompositor also directly
// manages GraphicsLayers related to FrameView scrolling.  See VisualViewport.h
// for a diagram of how these layers are wired.
//
// When root layer scrolling is enabled, PaintLayerCompositor does not create
// any of its own GraphicsLayers.  Instead the LayoutView's CLM is wired
// directly to the scroll layer of the visual viewport.
//
// In Slimming Paint v2, PaintLayerCompositor will be eventually replaced by
// PaintArtifactCompositor.

class CORE_EXPORT PaintLayerCompositor final : public GraphicsLayerClient {
  USING_FAST_MALLOC(PaintLayerCompositor);

 public:
  explicit PaintLayerCompositor(LayoutView&);
  ~PaintLayerCompositor() override;

  void UpdateIfNeededRecursive(DocumentLifecycle::LifecycleState target_state);

  // Return true if this LayoutView is in "compositing mode" (i.e. has one or
  // more composited Layers)
  bool InCompositingMode() const;
  // FIXME: Replace all callers with inCompositingMode and remove this function.
  bool StaleInCompositingMode() const;
  // This will make a compositing layer at the root automatically, and hook up
  // to the native view/window system.
  void SetCompositingModeEnabled(bool);

  // Returns true if the accelerated compositing is enabled
  bool HasAcceleratedCompositing() const {
    return has_accelerated_compositing_;
  }

  bool PreferCompositingToLCDTextEnabled() const;

  bool RootShouldAlwaysComposite() const;

  // Copy the accelerated compositing related flags from Settings
  void UpdateAcceleratedCompositingSettings();

  // Used to indicate that a compositing update will be needed for the next
  // frame that gets drawn.
  void SetNeedsCompositingUpdate(CompositingUpdateType);

  void DidLayout();

  // Whether layer's compositedLayerMapping needs a GraphicsLayer to clip
  // z-order children of the given Layer.
  bool ClipsCompositingDescendants(const PaintLayer*) const;

  // Whether the given layer needs an extra 'contents' layer.
  bool NeedsContentsCompositingLayer(const PaintLayer*) const;

  // Issue paint invalidations of the appropriate layers when the given Layer
  // starts or stops being composited.
  void PaintInvalidationOnCompositingChange(PaintLayer*);

  void FullyInvalidatePaint();

  PaintLayer* RootLayer() const;

  GraphicsLayer* ContainerLayer() const { return container_layer_.get(); }
  GraphicsLayer* FrameScrollLayer() const { return scroll_layer_.get(); }
  GraphicsLayer* LayerForHorizontalScrollbar() const {
    return layer_for_horizontal_scrollbar_.get();
  }
  GraphicsLayer* LayerForVerticalScrollbar() const {
    return layer_for_vertical_scrollbar_.get();
  }
  GraphicsLayer* LayerForScrollCorner() const {
    return layer_for_scroll_corner_.get();
  }

  // In root layer scrolling mode, returns the LayoutView's main GraphicsLayer.
  // In non-RLS mode, returns the outermost PaintLayerCompositor layer.
  GraphicsLayer* RootGraphicsLayer() const;

  // Returns the GraphicsLayer we should start painting from. This can differ
  // from above in some cases, e.g.  when the RootGraphicsLayer is detached and
  // swapped out for an overlay video layer.
  GraphicsLayer* PaintRootGraphicsLayer() const;

  // In root layer scrolling mode, this is the LayoutView's scroll layer.
  // In non-RLS mode, this is the same as frameScrollLayer().
  GraphicsLayer* ScrollLayer() const;

  void UpdateRootLayerPosition();

  void SetIsInWindow(bool);

  static PaintLayerCompositor* FrameContentsCompositor(LayoutEmbeddedContent&);
  // Return true if the layers changed.
  static bool AttachFrameContentLayersToIframeLayer(LayoutEmbeddedContent&);

  // Update the geometry of the layers used for clipping and scrolling in
  // frames.
  void FrameViewDidChangeLocation(const IntPoint& contents_offset);
  void FrameViewDidChangeSize();
  void FrameViewDidScroll();
  void FrameViewScrollbarsExistenceDidChange();

  std::unique_ptr<JSONObject> LayerTreeAsJSON(LayerTreeFlags) const;

  void UpdateTrackingRasterInvalidations();

  String DebugName(const GraphicsLayer*) const override;
  DocumentLifecycle& Lifecycle() const;

  void UpdatePotentialCompositingReasonsFromStyle(PaintLayer&);

  // Whether the layer could ever be composited.
  bool CanBeComposited(const PaintLayer*) const;

  // FIXME: Move allocateOrClearCompositedLayerMapping to
  // CompositingLayerAssigner once we've fixed the compositing chicken/egg
  // issues.
  bool AllocateOrClearCompositedLayerMapping(
      PaintLayer*,
      CompositingStateTransitionType composited_layer_update);

  bool InOverlayFullscreenVideo() const { return in_overlay_fullscreen_video_; }

  bool IsRootScrollerAncestor() const;

  // GraphicsLayerClient implementation
  bool ShouldThrottleRendering() const override;
  bool IsTrackingRasterInvalidations() const override;

 private:
#if DCHECK_IS_ON()
  void AssertNoUnresolvedDirtyBits();
#endif

  void UpdateIfNeededRecursiveInternal(
      DocumentLifecycle::LifecycleState target_state,
      CompositingReasonsStats&);

  // GraphicsLayerClient implementation
  bool NeedsRepaint(const GraphicsLayer&) const override { return true; }
  IntRect ComputeInterestRect(const GraphicsLayer*,
                              const IntRect&) const override;
  void PaintContents(const GraphicsLayer*,
                     GraphicsContext&,
                     GraphicsLayerPaintingPhase,
                     const IntRect& interest_rect) const override;

  void UpdateWithoutAcceleratedCompositing(CompositingUpdateType);
  void UpdateIfNeeded(DocumentLifecycle::LifecycleState target_state,
                      CompositingReasonsStats&);

  void EnsureRootLayer();
  void DestroyRootLayer();

  void AttachRootLayer();
  void DetachRootLayer();

  void AttachCompositorTimeline();
  void DetachCompositorTimeline();

  void UpdateOverflowControlsLayers();

  Page* GetPage() const;

  ScrollingCoordinator* GetScrollingCoordinator() const;

  void EnableCompositingModeIfNeeded();

  bool RequiresHorizontalScrollbarLayer() const;
  bool RequiresVerticalScrollbarLayer() const;
  bool RequiresScrollCornerLayer() const;
  void ShowScrollbarLayersIfNeeded();

  void ApplyOverlayFullscreenVideoAdjustmentIfNeeded();

  void UpdateContainerSizes();

  // Checks the given graphics layer against the compositor's horizontal and
  // vertical scrollbar graphics layers, returning the associated Scrollbar
  // instance if any, else nullptr.
  Scrollbar* GraphicsLayerToScrollbar(const GraphicsLayer*) const;

  bool IsMainFrame() const;
  VisualViewport& GetVisualViewport() const;
  GraphicsLayer* ParentForContentLayers(
      GraphicsLayer* child_frame_parent_candidate = nullptr) const;

  LayoutView& layout_view_;

  CompositingReasonFinder compositing_reason_finder_;

  CompositingUpdateType pending_update_type_;

  bool has_accelerated_compositing_;
  bool compositing_;

  // The root layer doesn't composite if it's a non-scrollable frame.
  // So, after a layout we set this dirty bit to know that we need
  // to recompute whether the root layer should composite even if
  // none of its descendants composite.
  // FIXME: Get rid of all the callers of setCompositingModeEnabled
  // except the one in updateIfNeeded, then rename this to
  // m_compositingDirty.
  bool root_should_always_composite_dirty_;
  bool in_overlay_fullscreen_video_;

  enum RootLayerAttachment {
    kRootLayerUnattached,
    kRootLayerPendingAttachViaChromeClient,
    kRootLayerAttachedViaChromeClient,
    kRootLayerAttachedViaEnclosingFrame
  };
  RootLayerAttachment root_layer_attachment_;

  // Outermost layer, holds overflow controls and the container layer
  std::unique_ptr<GraphicsLayer> overflow_controls_host_layer_;

  // Clips for iframe content
  std::unique_ptr<GraphicsLayer> container_layer_;

  // Scrolls with the FrameView
  std::unique_ptr<GraphicsLayer> scroll_layer_;

  // Innermost layer, parent of LayoutView main GraphicsLayer
  std::unique_ptr<GraphicsLayer> root_content_layer_;

  // Layers for overflow controls
  std::unique_ptr<GraphicsLayer> layer_for_horizontal_scrollbar_;
  std::unique_ptr<GraphicsLayer> layer_for_vertical_scrollbar_;
  std::unique_ptr<GraphicsLayer> layer_for_scroll_corner_;

  FRIEND_TEST_ALL_PREFIXES(FrameThrottlingTest,
                           IntersectionObservationOverridesThrottling);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_PAINT_LAYER_COMPOSITOR_H_
