Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[XB1] Add device lost handling #4628

Open
wants to merge 1 commit into
base: 24.lts.1+
Choose a base branch
from
Open
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
19 changes: 19 additions & 0 deletions cobalt/renderer/backend/egl/graphics_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "cobalt/renderer/backend/egl/utils.h"
#include "cobalt/renderer/egl_and_gles.h"
#include "starboard/configuration.h"
#include "starboard/extension/egl_context_lost_handler.h"

#if defined(GLES3_SUPPORTED)
#error "Support for gles3 features has been deprecated."
Expand Down Expand Up @@ -251,6 +252,9 @@ void GraphicsContextEGL::SafeEglMakeCurrent(RenderTargetEGL* surface) {
// a thread can result in global allocations being made that are never freed.
ANNOTATE_SCOPED_MEMORY_LEAK;

if (error_context_lost_) {
return;
}
EGLSurface egl_surface = surface->GetSurface();

// This should only be used with egl surfaces (not framebuffer objects).
Expand Down Expand Up @@ -279,6 +283,21 @@ void GraphicsContextEGL::SafeEglMakeCurrent(RenderTargetEGL* surface) {
surface->set_surface_bad();
egl_surface = null_surface_->GetSurface();
EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_));
} else if (make_current_error == EGL_CONTEXT_LOST) {
const CobaltExtensionEglContextLostHandlerApi* context_lost_handler =
static_cast<const CobaltExtensionEglContextLostHandlerApi*>(
SbSystemGetExtension(kCobaltExtensionEglContextLostHandlerName));
if (context_lost_handler &&
strcmp(context_lost_handler->name,
kCobaltExtensionEglContextLostHandlerName) == 0 &&
context_lost_handler->version >= 1) {
error_context_lost_ = true;
EGL_CALL(eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT));
context_lost_handler->HandleEglContextLost();
} else {
NOTREACHED() << "EGL_CONTEXT_LOST when calling eglMakeCurrent().";
}
} else {
NOTREACHED() << "Unexpected error when calling eglMakeCurrent().";
}
Expand Down
2 changes: 2 additions & 0 deletions cobalt/renderer/backend/egl/graphics_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ class GraphicsContextEGL : public GraphicsContext {
// OpenGL ES implementation.
bool bgra_format_supported_;

bool error_context_lost_ = false;

// Data required to provide BlitToRenderTarget() functionality via OpenGL ES.
GLuint blit_vertex_shader_;
GLuint blit_fragment_shader_;
Expand Down
46 changes: 46 additions & 0 deletions starboard/extension/egl_context_lost_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2025 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef STARBOARD_EXTENSION_EGL_CONTEXT_LOST_HANDLER_H_
#define STARBOARD_EXTENSION_EGL_CONTEXT_LOST_HANDLER_H_

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define kCobaltExtensionEglContextLostHandlerName \
"dev.cobalt.extension.EglContextLostHandler"

typedef struct CobaltExtensionEglContextLostHandlerApi {
// Name should be the string |kCobaltExtensionEglContextLostHandlerName|.
// This helps to validate that the extension API is correct.
const char* name;

// This specifies the version of the API that is implemented.
uint32_t version;

// The fields below this point were added in version 1 or later.

// Called when EGL_CONTEXT_LOST error is detected.
void (*HandleEglContextLost)();

} CobaltExtensionEglContextLostHandlerApi;

#ifdef __cplusplus
} // extern "C"
#endif

#endif // STARBOARD_EXTENSION_EGL_CONTEXT_LOST_HANDLER_H_
21 changes: 21 additions & 0 deletions starboard/extension/extension_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "starboard/extension/configuration.h"
#include "starboard/extension/crash_handler.h"
#include "starboard/extension/cwrappers.h"
#include "starboard/extension/egl_context_lost_handler.h"
#include "starboard/extension/enhanced_audio.h"
#include "starboard/extension/font.h"
#include "starboard/extension/free_space.h"
Expand Down Expand Up @@ -527,5 +528,25 @@ TEST(ExtensionTest, PlayerConfiguration) {
}
}

TEST(ExtensionTest, EglContextLostHandler) {
typedef CobaltExtensionEglContextLostHandlerApi ExtensionApi;
const char* kExtensionName = kCobaltExtensionEglContextLostHandlerName;

const ExtensionApi* extension_api =
static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
if (!extension_api) {
return;
}

EXPECT_STREQ(extension_api->name, kExtensionName);
EXPECT_EQ(extension_api->version, 1u);
EXPECT_NE(extension_api->HandleEglContextLost, nullptr);

const ExtensionApi* second_extension_api =
static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
EXPECT_EQ(second_extension_api, extension_api)
<< "Extension struct should be a singleton";
}

} // namespace extension
} // namespace starboard
2 changes: 2 additions & 0 deletions starboard/xb1/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ static_library("starboard_platform") {
"shared/configuration.cc",
"shared/configuration.h",
"shared/configuration_constants.cc",
"shared/egl_context_lost_handler.cc",
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added an extension test.

"shared/egl_context_lost_handler.h",
"shared/system_get_extensions.cc",
"shared/system_get_path.cc",
]
Expand Down
61 changes: 61 additions & 0 deletions starboard/xb1/shared/egl_context_lost_handler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2025 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/xb1/shared/egl_context_lost_handler.h"

#include "starboard/extension/egl_context_lost_handler.h"
#include "starboard/shared/starboard/media/mime_supportability_cache.h"
#include "starboard/shared/uwp/application_uwp.h"

using starboard::shared::starboard::media::MimeSupportabilityCache;
using starboard::shared::uwp::ApplicationUwp;

namespace starboard {
namespace xb1 {
namespace shared {

namespace {

void HandleEglContextLost() {
MimeSupportabilityCache::GetInstance()->ClearCachedMimeSupportabilities();
ApplicationUwp::Get()->Inject(
new ApplicationUwp::Event(kSbEventTypeBlur, NULL, NULL));
ApplicationUwp::Get()->Inject(
new ApplicationUwp::Event(kSbEventTypeConceal, NULL, NULL));
ApplicationUwp::Get()->Inject(
new ApplicationUwp::Event(kSbEventTypeFreeze, NULL, NULL));

ApplicationUwp::Get()->Inject(
new ApplicationUwp::Event(kSbEventTypeUnfreeze, NULL, NULL));
ApplicationUwp::Get()->Inject(
new ApplicationUwp::Event(kSbEventTypeReveal, NULL, NULL));
ApplicationUwp::Get()->Inject(
new ApplicationUwp::Event(kSbEventTypeFocus, NULL, NULL));
}

const CobaltExtensionEglContextLostHandlerApi kEglContextLostHandlerApi = {
kCobaltExtensionEglContextLostHandlerName,
1,
&HandleEglContextLost,
};

} // namespace

const void* GetEglContextLostHandlerApi() {
return &kEglContextLostHandlerApi;
}

} // namespace shared
} // namespace xb1
} // namespace starboard
28 changes: 28 additions & 0 deletions starboard/xb1/shared/egl_context_lost_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2025 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef STARBOARD_XB1_SHARED_EGL_CONTEXT_LOST_HANDLER_H_
#define STARBOARD_XB1_SHARED_EGL_CONTEXT_LOST_HANDLER_H_

namespace starboard {
namespace xb1 {
namespace shared {

const void* GetEglContextLostHandlerApi();

} // namespace shared
} // namespace xb1
} // namespace starboard

#endif // STARBOARD_XB1_SHARED_EGL_CONTEXT_LOST_HANDLER_H_
5 changes: 5 additions & 0 deletions starboard/xb1/shared/system_get_extensions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@

#include "starboard/common/string.h"
#include "starboard/extension/configuration.h"
#include "starboard/extension/egl_context_lost_handler.h"
#include "starboard/extension/graphics.h"
#include "starboard/extension/media_session.h"
#include "starboard/shared/uwp/xb1_media_session_client.h"
#include "starboard/shared/win32/graphics.h"
#include "starboard/xb1/shared/configuration.h"
#include "starboard/xb1/shared/egl_context_lost_handler.h"

const void* SbSystemGetExtension(const char* name) {
if (strcmp(name, kCobaltExtensionGraphicsName) == 0) {
Expand All @@ -32,5 +34,8 @@ const void* SbSystemGetExtension(const char* name) {
if (strcmp(name, kCobaltExtensionMediaSessionName) == 0) {
return starboard::shared::uwp::GetMediaSessionApi();
}
if (strcmp(name, kCobaltExtensionEglContextLostHandlerName) == 0) {
return starboard::xb1::shared::GetEglContextLostHandlerApi();
}
return NULL;
}
Loading