Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit eb7178e

Browse files
committed
[android] set presentation time via eglPresentationTimeANDROID
Attempt to reland: #29727 TODO: 1. This isn't right in the cases where the frame has been resubmitted. 2. This hasn't been wired for impeller yet.
1 parent 02590c7 commit eb7178e

File tree

7 files changed

+57
-7
lines changed

7 files changed

+57
-7
lines changed

flow/surface_frame.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "flutter/common/graphics/gl_context_switch.h"
1212
#include "flutter/display_list/display_list_canvas_recorder.h"
1313
#include "flutter/fml/macros.h"
14+
#include "flutter/fml/time/time_point.h"
1415
#include "third_party/skia/include/core/SkCanvas.h"
1516
#include "third_party/skia/include/core/SkSurface.h"
1617

@@ -72,6 +73,10 @@ class SurfaceFrame {
7273
//
7374
// Corresponds to EGL_KHR_partial_update
7475
std::optional<SkIRect> buffer_damage;
76+
77+
// Time at which this frame is scheduled to be presented. This is a hint
78+
// that can be passed to the platform to drop queued frames.
79+
fml::TimePoint presentation_time;
7580
};
7681

7782
bool Submit();

shell/common/rasterizer.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,9 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe(
604604
}
605605

606606
SurfaceFrame::SubmitInfo submit_info;
607+
// TODO (kaushikiska): this can be in the past and might need to get snapped
608+
// to future as this frame could have been resubmitted.
609+
submit_info.presentation_time = frame_timings_recorder.GetVsyncTargetTime();
607610
if (damage) {
608611
submit_info.frame_damage = damage->GetFrameDamage();
609612
submit_info.buffer_damage = damage->GetBufferDamage();

shell/gpu/gpu_surface_gl_delegate.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ struct GLPresentInfo {
2929
// Damage is a hint to compositor telling it which parts of front buffer
3030
// need to be updated
3131
const std::optional<SkIRect>& damage;
32+
33+
// Time at which this frame is scheduled to be presented. This is a hint
34+
// that can be passed to the platform to drop queued frames.
35+
std::optional<fml::TimePoint> presentation_time = std::nullopt;
3236
};
3337

3438
class GPUSurfaceGLDelegate {

shell/gpu/gpu_surface_gl_impeller.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceGLImpeller::AcquireFrame(
6363
GLPresentInfo present_info = {
6464
.fbo_id = 0,
6565
.damage = std::nullopt,
66+
// TODO (kaushikiska): wire-up presentation time to impeller backend.
67+
.presentation_time = std::nullopt,
6668
};
6769
delegate->GLContextPresent(present_info);
6870
}

shell/platform/android/android_egl_surface.cc

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ void LogLastEGLError() {
6060
FML_LOG(ERROR) << "Unknown EGL Error";
6161
}
6262

63+
namespace {
64+
65+
static bool HasExtension(const char* extensions, const char* name) {
66+
const char* r = strstr(extensions, name);
67+
auto len = strlen(name);
68+
// check that the extension name is terminated by space or null terminator
69+
return r != nullptr && (r[len] == ' ' || r[len] == 0);
70+
}
71+
72+
} // namespace
73+
6374
class AndroidEGLSurfaceDamage {
6475
public:
6576
void init(EGLDisplay display, EGLContext context) {
@@ -170,13 +181,6 @@ class AndroidEGLSurfaceDamage {
170181

171182
bool partial_redraw_supported_;
172183

173-
bool HasExtension(const char* extensions, const char* name) {
174-
const char* r = strstr(extensions, name);
175-
auto len = strlen(name);
176-
// check that the extension name is terminated by space or null terminator
177-
return r != nullptr && (r[len] == ' ' || r[len] == 0);
178-
}
179-
180184
std::list<SkIRect> damage_history_;
181185
};
182186

@@ -188,6 +192,14 @@ AndroidEGLSurface::AndroidEGLSurface(EGLSurface surface,
188192
context_(context),
189193
damage_(std::make_unique<AndroidEGLSurfaceDamage>()) {
190194
damage_->init(display_, context);
195+
196+
const char* extensions = eglQueryString(display, EGL_EXTENSIONS);
197+
198+
if (HasExtension(extensions, "EGL_ANDROID_presentation_time")) {
199+
presentation_time_proc_ =
200+
reinterpret_cast<PFNEGLPRESENTATIONTIMEANDROIDPROC>(
201+
eglGetProcAddress("eglPresentationTimeANDROID"));
202+
}
191203
}
192204

193205
AndroidEGLSurface::~AndroidEGLSurface() {
@@ -240,6 +252,16 @@ void AndroidEGLSurface::SetDamageRegion(
240252
damage_->SetDamageRegion(display_, surface_, buffer_damage);
241253
}
242254

255+
bool AndroidEGLSurface::SetPresentationTime(
256+
const fml::TimePoint& presentation_time) {
257+
if (presentation_time_proc_) {
258+
const auto time_ns = presentation_time.ToEpochDelta().ToNanoseconds();
259+
return presentation_time_proc_(display_, surface_, time_ns);
260+
} else {
261+
return false;
262+
}
263+
}
264+
243265
bool AndroidEGLSurface::SwapBuffers(
244266
const std::optional<SkIRect>& surface_damage) {
245267
TRACE_EVENT0("flutter", "AndroidContextGL::SwapBuffers");

shell/platform/android/android_egl_surface.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_EGL_SURFACE_H_
66
#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_EGL_SURFACE_H_
77

8+
#include <EGL/egl.h>
9+
#include <EGL/eglext.h>
10+
#include <KHR/khrplatform.h>
811
#include <optional>
912

1013
#include "flutter/fml/macros.h"
14+
#include "flutter/fml/time/time_point.h"
1115
#include "flutter/shell/platform/android/android_environment_gl.h"
1216
#include "third_party/skia/include/core/SkRect.h"
1317

@@ -77,6 +81,12 @@ class AndroidEGLSurface {
7781
// eglSetDamageRegionKHR
7882
void SetDamageRegion(const std::optional<SkIRect>& buffer_damage);
7983

84+
//----------------------------------------------------------------------------
85+
/// @brief Sets the presentation time for the current surface. This
86+
// corresponds to calling eglPresentationTimeAndroid when
87+
// available.
88+
bool SetPresentationTime(const fml::TimePoint& presentation_time);
89+
8090
//----------------------------------------------------------------------------
8191
/// @brief This only applies to on-screen surfaces such as those created
8292
/// by `AndroidContextGL::CreateOnscreenSurface`.
@@ -98,6 +108,7 @@ class AndroidEGLSurface {
98108
const EGLDisplay display_;
99109
const EGLContext context_;
100110
std::unique_ptr<AndroidEGLSurfaceDamage> damage_;
111+
PFNEGLPRESENTATIONTIMEANDROIDPROC presentation_time_proc_;
101112
};
102113

103114
} // namespace flutter

shell/platform/android/android_surface_gl_skia.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ void AndroidSurfaceGLSkia::GLContextSetDamageRegion(
156156
bool AndroidSurfaceGLSkia::GLContextPresent(const GLPresentInfo& present_info) {
157157
FML_DCHECK(IsValid());
158158
FML_DCHECK(onscreen_surface_);
159+
if (present_info.presentation_time) {
160+
onscreen_surface_->SetPresentationTime(*present_info.presentation_time);
161+
}
159162
return onscreen_surface_->SwapBuffers(present_info.damage);
160163
}
161164

0 commit comments

Comments
 (0)