// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_H_
#define CONTENT_PUBLIC_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_H_
#include <stddef.h>
#include <memory>
#include <optional>
#include "base/memory/ref_counted.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "components/viz/common/frame_timing_details_map.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/resources/returned_resource.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
class SkCanvas;
namespace gfx {
class Point;
class PointF;
class Transform;
} // namespace gfx
namespace viz {
class CompositorFrame;
class BeginFrameSource;
}
namespace content {
class SynchronousCompositorClient;
class WebContents;
// Interface for embedders that wish to direct compositing operations
// synchronously under their own control. Only meaningful when the
// kEnableSyncrhonousRendererCompositor flag is specified.
class CONTENT_EXPORT SynchronousCompositor {
public:
// Must be called once per WebContents instance. Will create the compositor
// instance as needed, but only if |client| is non-nullptr.
static void SetClientForWebContents(WebContents* contents,
SynchronousCompositorClient* client);
struct Frame {
Frame();
Frame(const Frame&) = delete;
Frame& operator=(const Frame&) = delete;
~Frame();
// Movable type.
Frame(Frame&& rhs);
Frame& operator=(Frame&& rhs);
uint32_t layer_tree_frame_sink_id;
std::unique_ptr<viz::CompositorFrame> frame;
// Invalid if |frame| is nullptr.
viz::LocalSurfaceId local_surface_id;
std::optional<viz::HitTestRegionList> hit_test_region_list;
};
class FrameFuture : public base::RefCountedThreadSafe<FrameFuture> {
public:
FrameFuture();
void SetFrame(std::unique_ptr<Frame> frame);
std::unique_ptr<Frame> GetFrame();
private:
friend class base::RefCountedThreadSafe<FrameFuture>;
~FrameFuture();
base::WaitableEvent waitable_event_;
std::unique_ptr<Frame> frame_;
#if DCHECK_IS_ON()
bool waited_ = false;
#endif
};
virtual void OnCompositorVisible() = 0;
virtual void OnCompositorHidden() = 0;
// "On demand" hardware draw. Parameters are used by compositor for this draw.
// |viewport_size| is the current size to improve results during resize.
// |viewport_rect_for_tile_priority| and |transform_for_tile_priority| are
// used to customize the tiling decisions of compositor.
virtual scoped_refptr<FrameFuture> DemandDrawHwAsync(
const gfx::Size& viewport_size,
const gfx::Rect& viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority) = 0;
// For delegated rendering, return resources from parent compositor to this.
// Note that all resources must be returned before ReleaseHwDraw.
virtual void ReturnResources(
uint32_t layer_tree_frame_sink_id,
std::vector<viz::ReturnedResource> resources) = 0;
// Notifies the client when a directive for ViewTransition, submitted in
// a previous CompositorFrame, has finished executing.
virtual void OnCompositorFrameTransitionDirectiveProcessed(
uint32_t layer_tree_frame_sink_id,
uint32_t sequence_id) = 0;
virtual void DidPresentCompositorFrames(
viz::FrameTimingDetailsMap timing_details,
uint32_t frame_token) = 0;
// "On demand" SW draw, into the supplied canvas (observing the transform
// and clip set there-in).
// `software canvas` being true means drawing happens immediately instead
// of being cached, which allows more efficient drawing.
virtual bool DemandDrawSw(SkCanvas* canvas, bool software_canvas) = 0;
// Set the memory limit policy of this compositor.
virtual void SetMemoryPolicy(size_t bytes_limit) = 0;
// Returns the higher of x or y scroll velocity. Only returns valid value
// after begin frame and before DemandDraw of a frame.
virtual float GetVelocityInPixelsPerSecond() = 0;
// Called during renderer swap. Should push any relevant up to
// SynchronousCompositorClient.
virtual void DidBecomeActive() = 0;
// Should be called by the embedder after the embedder had modified the
// scroll offset of the root layer. |root_offset| must be in physical pixel
// scale.
virtual void DidChangeRootLayerScrollOffset(
const gfx::PointF& root_offset) = 0;
// Allows embedder to synchronously update the zoom level, ie page scale
// factor, around the anchor point.
virtual void SynchronouslyZoomBy(float zoom_delta,
const gfx::Point& anchor) = 0;
// Called by the embedder to notify that the OnComputeScroll step is happening
// and if any input animation is active, it should tick now.
virtual void OnComputeScroll(base::TimeTicks animation_time) = 0;
// Sets BeginFrameSource to use
virtual void SetBeginFrameSource(
viz::BeginFrameSource* begin_frame_source) = 0;
// Called when client invalidated because it was necessary for drawing sub
// clients. Used with viz for webview only.
virtual void DidInvalidate() = 0;
// Called when embedder has evicted the previous compositor frame. So renderer
// needs to submit next frame with new LocalSurfaceId.
virtual void WasEvicted() = 0;
protected:
virtual ~SynchronousCompositor() {}
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_ANDROID_SYNCHRONOUS_COMPOSITOR_H_