#ifndef ANDROID_WEBVIEW_BROWSER_GFX_HARDWARE_RENDERER_H_
#define ANDROID_WEBVIEW_BROWSER_GFX_HARDWARE_RENDERER_H_
#include <memory>
#include "android_webview/browser/gfx/child_frame.h"
#include "android_webview/browser/gfx/output_surface_provider_webview.h"
#include "android_webview/browser/gfx/root_frame_sink.h"
#include "base/memory/raw_ptr.h"
#include "base/threading/thread_checker.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "ui/gfx/android/android_surface_control_compat.h"
#include "ui/gfx/color_space.h"
namespace android_webview {
class AwVulkanContextProvider;
class RenderThreadManager;
struct OverlaysParams {
enum class Mode {
Disabled,
Enabled,
};
typedef ASurfaceControl* (*GetSurfaceControlFn)();
typedef void (*MergeTransactionFn)(ASurfaceTransaction*);
Mode overlays_mode = Mode::Disabled;
GetSurfaceControlFn get_surface_control = nullptr;
MergeTransactionFn merge_transaction = nullptr;
};
struct HardwareRendererDrawParams {
bool operator==(const HardwareRendererDrawParams& other) const;
bool operator!=(const HardwareRendererDrawParams& other) const;
int clip_left;
int clip_top;
int clip_right;
int clip_bottom;
int width;
int height;
float transform[16];
gfx::ColorSpace color_space;
};
using ReportRenderingThreadsCallback =
base::OnceCallback<void(const pid_t*, size_t)>;
class HardwareRenderer {
public:
static ChildFrameQueue WaitAndPruneFrameQueue(ChildFrameQueue* child_frames);
HardwareRenderer(RenderThreadManager* state,
RootFrameSinkGetter root_frame_sink_getter,
AwVulkanContextProvider* context_provider);
HardwareRenderer(const HardwareRenderer&) = delete;
HardwareRenderer& operator=(const HardwareRenderer&) = delete;
~HardwareRenderer();
void Draw(const HardwareRendererDrawParams& params,
const OverlaysParams& overlays_params,
ReportRenderingThreadsCallback report_rendering_threads_callback);
void CommitFrame();
void SetChildFrameForTesting(std::unique_ptr<ChildFrame> child_frame);
void RemoveOverlays(OverlaysParams::MergeTransactionFn merge_transaction);
void AbandonContext();
private:
class OnViz;
void InitializeOnViz(RootFrameSinkGetter root_frame_sink_getter);
bool IsUsingVulkan() const;
bool IsUsingANGLEOverGL() const;
void MergeTransactionIfNeeded(
OverlaysParams::MergeTransactionFn merge_transaction);
void ReturnChildFrame(std::unique_ptr<ChildFrame> child_frame);
void ReturnResourcesToCompositor(std::vector<viz::ReturnedResource> resources,
const viz::FrameSinkId& frame_sink_id,
uint32_t layer_tree_frame_sink_id);
void ReportDrawMetric(const HardwareRendererDrawParams& params);
void DrawAndSwap(
const HardwareRendererDrawParams& params,
const OverlaysParams& overlays_params,
ReportRenderingThreadsCallback report_rendering_threads_callback);
void MarkAllowContextLoss();
THREAD_CHECKER(render_thread_checker_);
const raw_ptr<RenderThreadManager> render_thread_manager_;
typedef void* EGLContext;
EGLContext last_egl_context_;
ChildFrameQueue child_frame_queue_;
std::unique_ptr<ChildFrame> child_frame_;
bool did_invalidate_ = false;
bool did_submit_compositor_frame_ = false;
gfx::Point scroll_offset_;
uint32_t last_committed_layer_tree_frame_sink_id_ = 0u;
HardwareRendererDrawParams last_draw_params_ = {};
float device_scale_factor_ = 0;
viz::SurfaceId surface_id_;
OutputSurfaceProviderWebView output_surface_provider_;
std::unique_ptr<OnViz> on_viz_;
bool report_rendering_threads_ = false;
base::TimeDelta preferred_frame_interval_;
};
}
#endif