Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions shell/platform/android/android_context_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,40 @@ bool AndroidEGLSurface::IsValid() const {
return surface_ != EGL_NO_SURFACE;
}

bool AndroidEGLSurface::MakeCurrent() const {
bool AndroidEGLSurface::IsContextCurrent() const {
EGLContext current_egl_context = eglGetCurrentContext();
Copy link
Member

@jason-simmons jason-simmons Apr 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check eglGetCurrentSurface and eglGetCurrentDisplay in addition to the EGL context

if (context_ != current_egl_context) {
return false;
}

EGLDisplay current_egl_display = eglGetCurrentDisplay();
if (display_ != current_egl_display) {
return false;
}

EGLSurface draw_surface = eglGetCurrentSurface(EGL_DRAW);
if (draw_surface != surface_) {
return false;
}

EGLSurface read_surface = eglGetCurrentSurface(EGL_READ);
if (read_surface != surface_) {
return false;
}

return true;
}

AndroidEGLSurfaceMakeCurrentStatus AndroidEGLSurface::MakeCurrent() const {
if (IsContextCurrent()) {
return AndroidEGLSurfaceMakeCurrentStatus::kSuccessAlreadyCurrent;
}
if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) {
FML_LOG(ERROR) << "Could not make the context current";
LogLastEGLError();
return false;
return AndroidEGLSurfaceMakeCurrentStatus::kFailure;
}
return true;
return AndroidEGLSurfaceMakeCurrentStatus::kSuccessMadeCurrent;
}

void AndroidEGLSurface::SetDamageRegion(
Expand Down Expand Up @@ -350,7 +377,8 @@ AndroidContextGL::~AndroidContextGL() {
if (main_context) {
std::unique_ptr<AndroidEGLSurface> pbuffer_surface =
CreatePbufferSurface();
if (pbuffer_surface->MakeCurrent()) {
auto status = pbuffer_surface->MakeCurrent();
if (status != AndroidEGLSurfaceMakeCurrentStatus::kFailure) {
main_context->releaseResourcesAndAbandonContext();
main_context.reset();
ClearCurrent();
Expand Down
15 changes: 14 additions & 1 deletion shell/platform/android/android_context_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ namespace flutter {
///
class AndroidEGLSurfaceDamage;

/// Result of calling MakeCurrent on AndroidEGLSurface.
enum class AndroidEGLSurfaceMakeCurrentStatus {
/// Success, the egl context for the surface was already current.
kSuccessAlreadyCurrent,
/// Success, the egl context for the surface made current.
kSuccessMadeCurrent,
/// Failed to make the egl context for the surface current.
kFailure,
};

class AndroidEGLSurface {
public:
AndroidEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context);
Expand All @@ -43,7 +53,7 @@ class AndroidEGLSurface {
///
/// @return Whether the surface was made current.
///
bool MakeCurrent() const;
AndroidEGLSurfaceMakeCurrentStatus MakeCurrent() const;

//----------------------------------------------------------------------------
///
Expand Down Expand Up @@ -81,6 +91,9 @@ class AndroidEGLSurface {
SkISize GetSize() const;

private:
/// Returns true if the EGLContext held is current for the display and surface
bool IsContextCurrent() const;

const EGLSurface surface_;
const EGLDisplay display_;
const EGLContext context_;
Expand Down
24 changes: 24 additions & 0 deletions shell/platform/android/android_context_gl_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,30 @@ TEST(AndroidContextGl, MSAAx4) {
&sample_count);
EXPECT_EQ(sample_count, 4);
}

TEST(AndroidContextGl, EnsureMakeCurrentChecksCurrentContextStatus) {
GrMockOptions main_context_options;
sk_sp<GrDirectContext> main_context =
GrDirectContext::MakeMock(&main_context_options);
auto environment = fml::MakeRefCounted<AndroidEnvironmentGL>();
std::string thread_label =
::testing::UnitTest::GetInstance()->current_test_info()->name();

ThreadHost thread_host(ThreadHost::ThreadHostConfig(
thread_label,
ThreadHost::Type::UI | ThreadHost::Type::RASTER | ThreadHost::Type::IO));
TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host);
auto context = std::make_unique<AndroidContextGL>(
AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0);

auto pbuffer_surface = context->CreatePbufferSurface();
auto status = pbuffer_surface->MakeCurrent();
EXPECT_EQ(AndroidEGLSurfaceMakeCurrentStatus::kSuccessMadeCurrent, status);

// context already current, so status must reflect that.
status = pbuffer_surface->MakeCurrent();
EXPECT_EQ(AndroidEGLSurfaceMakeCurrentStatus::kSuccessAlreadyCurrent, status);
}
} // namespace android
} // namespace testing
} // namespace flutter
6 changes: 4 additions & 2 deletions shell/platform/android/android_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) {

bool AndroidSurfaceGL::ResourceContextMakeCurrent() {
FML_DCHECK(IsValid());
return offscreen_surface_->MakeCurrent();
auto status = offscreen_surface_->MakeCurrent();
return status != AndroidEGLSurfaceMakeCurrentStatus::kFailure;
}

bool AndroidSurfaceGL::ResourceContextClearCurrent() {
Expand Down Expand Up @@ -116,8 +117,9 @@ bool AndroidSurfaceGL::SetNativeWindow(
std::unique_ptr<GLContextResult> AndroidSurfaceGL::GLContextMakeCurrent() {
FML_DCHECK(IsValid());
FML_DCHECK(onscreen_surface_);
auto status = onscreen_surface_->MakeCurrent();
auto default_context_result = std::make_unique<GLContextDefaultResult>(
onscreen_surface_->MakeCurrent());
status != AndroidEGLSurfaceMakeCurrentStatus::kFailure);
return std::move(default_context_result);
}

Expand Down