blob: d5f35d2ccfb21b231e235dbfae3eee96a488eb20 [file]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_ACCELERATED_WIDGET_MAC_CA_LAYER_TREE_COORDINATOR_H_
#define UI_ACCELERATED_WIDGET_MAC_CA_LAYER_TREE_COORDINATOR_H_
#include <queue>
#include "base/containers/queue.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
#include "ui/gfx/ca_layer_result.h"
#include "ui/gfx/presentation_feedback.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/presenter.h"
@class CAContext;
@class CALayer;
@protocol MTLDevice;
namespace ui {
class CARendererLayerTree;
using BufferPresentedCallback =
base::RepeatingCallback<void(gl::Presenter::PresentationCallback callback,
const gfx::PresentationFeedback& feedback)>;
using GLMakeCurrentCallback = base::RepeatingCallback<bool()>;
struct PresentedFrame {
PresentedFrame();
PresentedFrame(PresentedFrame&&);
PresentedFrame& operator=(PresentedFrame&&);
~PresentedFrame();
// The swap completion and presentation callbacks are made when
// the layers in `tree` are committed to CoreAnimation.
gl::Presenter::SwapCompletionCallback completion_callback;
gl::Presenter::PresentationCallback presentation_callback;
// Fences inserted before Present was called. Future frames will wait on these
// fences to ensure that our GPU work does not starve CoreAnimation.
std::vector<gfx::MTLSharedEventFence> backpressure_metal_fences;
std::unique_ptr<gl::GLFence> backpressure_gl_fence;
gfx::CALayerResult ca_layer_error_code = gfx::kCALayerSuccess;
// The timetick when the GPU has finished completing all the drawing commands
base::TimeTicks ready_timestamp;
// The tree structure and, for the currently displaying tree, the
// actually CALayers.
std::unique_ptr<CARendererLayerTree> layer_tree;
bool has_committed = false;
};
// A structure that holds the tree of CALayers to display composited content.
// The CALayer tree may consist of a GLRendererLayerTree if the OpenGL renderer
// is being used, or a CARendererLayerTree if the CoreAnimation renderer is
// being used.
//
// This is instantiated in the GPU process and sent to the browser process via
// the cross-process CoreAnimation API.
class ACCELERATED_WIDGET_MAC_EXPORT CALayerTreeCoordinator {
public:
CALayerTreeCoordinator(bool allow_av_sample_buffer_display_layer,
BufferPresentedCallback buffer_presented_callback,
GLMakeCurrentCallback gl_make_current_callback,
id<MTLDevice> metal_device);
CALayerTreeCoordinator(const CALayerTreeCoordinator&) = delete;
CALayerTreeCoordinator& operator=(const CALayerTreeCoordinator&) = delete;
virtual ~CALayerTreeCoordinator();
CALayer* root_ca_layer() const { return root_ca_layer_; }
// Set the composited frame's size.
void Resize(const gfx::Size& pixel_size, float scale_factor);
// Set the CALayer overlay error for the frame that is going to be presented.
void SetCALayerErrorCode(gfx::CALayerResult ca_layer_error_code);
// The CARendererLayerTree for the pending frame. This is used to construct
// the CALayer tree for the CoreAnimation renderer.
CARendererLayerTree* GetPendingCARendererLayerTree();
// The number of presented frames that are still waiting to be committed.
virtual int NumPendingSwaps() const;
virtual void Present(
gl::Presenter::SwapCompletionCallback completion_callback,
gl::Presenter::PresentationCallback presentation_callback);
// Wait on backpressure fences for the committed frame.
void ApplyBackpressure();
// Commit the presented frame's OpenGL backbuffer or CALayer tree to be
// attached to the root CALayer.
virtual void CommitPresentedFrameToCA(base::TimeDelta frame_interval,
base::TimeTicks display_time);
void SetMaxCALayerTrees(int cap_max_ca_layer_trees);
// Enqueue Metal backpressure fences for the current unpresented frame.
void EnqueueBackpressureFences(
std::vector<gfx::MTLSharedEventFence> metal_fences);
private:
const bool allow_remote_layers_ = true;
const bool allow_av_sample_buffer_display_layer_ = true;
gfx::Size pixel_size_;
float scale_factor_ = 1;
gfx::CALayerResult ca_layer_error_code_ = gfx::kCALayerSuccess;
// The max number of CARendererLayerTree allowed at the same time. It includes
// both the current tree and the pending trees.
size_t presented_ca_layer_trees_max_length_ = 2;
CAContext* __strong ca_context_;
// The root CALayer to display the current frame. This does not change
// over the lifetime of the object.
CALayer* __strong root_ca_layer_;
BufferPresentedCallback buffer_presented_callback_;
GLMakeCurrentCallback gl_make_current_callback_;
// This is needed to ensure synchronization between the display compositor and
// the HDRCopierLayer. See https://crbug.com/1372898
id<MTLDevice> __strong metal_device_;
// The frame that is currently under construction. It has had planes
// scheduled, but has not had Present() called yet. When Present() is called,
// it will be moved to |presented_frames_|.
std::unique_ptr<CARendererLayerTree> unpresented_ca_renderer_layer_tree_;
// Backpressure Metal fences for the current unpresented frame.
std::vector<gfx::MTLSharedEventFence> pending_backpressure_metal_fences_;
// The frames has been presented.
base::queue<PresentedFrame> presented_frames_;
};
} // namespace ui
#endif // UI_ACCELERATED_WIDGET_MAC_CA_LAYER_TREE_COORDINATOR_H_