-
Notifications
You must be signed in to change notification settings - Fork 463
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(🤖): Fix serious Android threading issue (#2749)
Every offscreen surfaces where sharing the OpenGL context even though they may be created from different thread. This can easily cause crashes, especially in viewRef.makeImageSnapshot which is using an offscreen surface. We sanitized the OpenGLContext to not have anything shared across threads.
- Loading branch information
1 parent
53a8db5
commit 6fbaeab
Showing
15 changed files
with
571 additions
and
621 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#include "OpenGLWindowContext.h" | ||
#include "GrAHardwareBufferUtils.h" | ||
|
||
#pragma clang diagnostic push | ||
#pragma clang diagnostic ignored "-Wdocumentation" | ||
|
||
#include "include/gpu/ganesh/SkImageGanesh.h" | ||
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h" | ||
#include "src/gpu/ganesh/gl/GrGLDefines.h" | ||
|
||
#pragma clang diagnostic pop | ||
|
||
namespace RNSkia { | ||
|
||
sk_sp<SkSurface> OpenGLWindowContext::getSurface() { | ||
if (_skSurface == nullptr) { | ||
|
||
struct ReleaseContext { | ||
std::unique_ptr<Surface> surface = nullptr; | ||
}; | ||
|
||
auto releaseCtx = new ReleaseContext(); | ||
releaseCtx->surface = _display->makeWindowSurface(_config, _window); | ||
_surface = releaseCtx->surface.get(); | ||
|
||
// Now make this one current | ||
_context->makeCurrent(*releaseCtx->surface); | ||
|
||
// Set up parameters for the render target so that it | ||
// matches the underlying OpenGL context. | ||
GrGLFramebufferInfo fboInfo; | ||
|
||
// We pass 0 as the framebuffer id, since the | ||
// underlying Skia GrGlGpu will read this when wrapping the context in the | ||
// render target and the GrGlGpu object. | ||
fboInfo.fFBOID = 0; | ||
fboInfo.fFormat = 0x8058; // GL_RGBA8 | ||
|
||
GLint stencil; | ||
glGetIntegerv(GL_STENCIL_BITS, &stencil); | ||
|
||
GLint samples; | ||
glGetIntegerv(GL_SAMPLES, &samples); | ||
|
||
auto colorType = kN32_SkColorType; | ||
|
||
auto maxSamples = | ||
_directContext->maxSurfaceSampleCountForColorType(colorType); | ||
|
||
if (samples > maxSamples) { | ||
samples = maxSamples; | ||
} | ||
|
||
auto renderTarget = GrBackendRenderTargets::MakeGL(_width, _height, samples, | ||
stencil, fboInfo); | ||
|
||
SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | ||
|
||
|
||
// Create surface object | ||
_skSurface = SkSurfaces::WrapBackendRenderTarget( | ||
_directContext, renderTarget, kBottomLeft_GrSurfaceOrigin, colorType, | ||
nullptr, &props, | ||
[](void *addr) { | ||
auto releaseCtx = reinterpret_cast<ReleaseContext *>(addr); | ||
delete releaseCtx; | ||
}, | ||
reinterpret_cast<void *>(releaseCtx)); | ||
} | ||
return _skSurface; | ||
} | ||
|
||
} // namespace RNSkia |
74 changes: 74 additions & 0 deletions
74
packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#pragma once | ||
|
||
#include "RNSkLog.h" | ||
|
||
#include <fbjni/fbjni.h> | ||
#include <jni.h> | ||
|
||
#include <android/native_window_jni.h> | ||
#include <android/surface_texture.h> | ||
#include <android/surface_texture_jni.h> | ||
#include <condition_variable> | ||
#include <memory> | ||
#include <thread> | ||
#include <unordered_map> | ||
|
||
#include "WindowContext.h" | ||
#include "opengl/Display.h" | ||
|
||
#pragma clang diagnostic push | ||
#pragma clang diagnostic ignored "-Wdocumentation" | ||
|
||
#include "include/core/SkCanvas.h" | ||
#include "include/core/SkColorSpace.h" | ||
#include "include/core/SkSurface.h" | ||
#include "include/gpu/ganesh/GrBackendSurface.h" | ||
#include "include/gpu/ganesh/GrDirectContext.h" | ||
#include "include/gpu/ganesh/SkSurfaceGanesh.h" | ||
#include "include/gpu/ganesh/gl/GrGLInterface.h" | ||
|
||
#pragma clang diagnostic pop | ||
|
||
namespace RNSkia { | ||
|
||
class OpenGLWindowContext : public WindowContext { | ||
public: | ||
OpenGLWindowContext(EGLConfig &config, Display *display, Context *context, | ||
GrDirectContext *directContext, ANativeWindow *window, | ||
int width, int height) | ||
: _config(config), _display(display), _directContext(directContext), | ||
_context(context), _window(window), _width(width), _height(height) {} | ||
|
||
~OpenGLWindowContext() { ANativeWindow_release(_window); } | ||
|
||
sk_sp<SkSurface> getSurface() override; | ||
|
||
void present() override { | ||
_context->makeCurrent(*_surface); | ||
_directContext->flushAndSubmit(); | ||
_surface->Present(); | ||
} | ||
|
||
void resize(int width, int height) override { | ||
_skSurface = nullptr; | ||
_width = width; | ||
_height = height; | ||
} | ||
|
||
int getWidth() override { return _width; }; | ||
|
||
int getHeight() override { return _height; }; | ||
|
||
private: | ||
ANativeWindow *_window; | ||
sk_sp<SkSurface> _skSurface = nullptr; | ||
EGLConfig _config; | ||
Context *_context; | ||
Surface* _surface; | ||
Display *_display; | ||
GrDirectContext *_directContext; | ||
int _width = 0; | ||
int _height = 0; | ||
}; | ||
|
||
} // namespace RNSkia |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,7 +71,6 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas( | |
return false; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
|
Oops, something went wrong.