Skip to content

Commit 53a8db5

Browse files
authored
fix(🍏): Fix performance regression on iOS (#2744)
fixes #2743 In v1.5.3, we introduced a regression where we would request the next frame twice leading to frame drop in half.
1 parent ef5d52e commit 53a8db5

6 files changed

+64
-75
lines changed

packages/skia/cpp/rnskia/DawnContext.h

+21-21
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ struct AsyncContext {
3636
};
3737

3838
struct SharedTextureContext {
39-
wgpu::SharedTextureMemory sharedTextureMemory;
40-
wgpu::Texture texture;
39+
wgpu::SharedTextureMemory sharedTextureMemory;
40+
wgpu::Texture texture;
4141
};
4242

4343
static void
@@ -111,7 +111,7 @@ class DawnContext {
111111
int height = static_cast<int>(IOSurfaceGetHeight(ioSurface));
112112
#else
113113
wgpu::SharedTextureMemoryAHardwareBufferDescriptor platformDesc;
114-
auto ahb = (AHardwareBuffer*)buffer;
114+
auto ahb = (AHardwareBuffer *)buffer;
115115
platformDesc.handle = ahb;
116116
platformDesc.useExternalFormat = true;
117117
AHardwareBuffer_Desc adesc;
@@ -122,13 +122,16 @@ class DawnContext {
122122

123123
wgpu::SharedTextureMemoryDescriptor desc = {};
124124
desc.nextInChain = &platformDesc;
125-
wgpu::SharedTextureMemory memory = backendContext.fDevice.ImportSharedTextureMemory(&desc);
125+
wgpu::SharedTextureMemory memory =
126+
backendContext.fDevice.ImportSharedTextureMemory(&desc);
126127

127128
wgpu::TextureDescriptor textureDesc;
128129
textureDesc.format = DawnUtils::PreferredTextureFormat;
129130
textureDesc.dimension = wgpu::TextureDimension::e2D;
130-
textureDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc;
131-
textureDesc.size = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1};
131+
textureDesc.usage =
132+
wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc;
133+
textureDesc.size = {static_cast<uint32_t>(width),
134+
static_cast<uint32_t>(height), 1};
132135

133136
wgpu::Texture texture = memory.CreateTexture(&textureDesc);
134137

@@ -137,26 +140,23 @@ class DawnContext {
137140
beginAccessDesc.fenceCount = 0;
138141
bool success = memory.BeginAccess(texture, &beginAccessDesc);
139142

140-
if (success) {
141-
skgpu::graphite::BackendTexture betFromView = skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
142-
auto result = SkImages::WrapTexture(
143-
getRecorder(),
144-
betFromView,
145-
DawnUtils::PreferedColorType,
146-
kPremul_SkAlphaType,
147-
nullptr,
148-
[](void* context) {
143+
if (success) {
144+
skgpu::graphite::BackendTexture betFromView =
145+
skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
146+
auto result = SkImages::WrapTexture(
147+
getRecorder(), betFromView, DawnUtils::PreferedColorType,
148+
kPremul_SkAlphaType, nullptr,
149+
[](void *context) {
149150
auto ctx = static_cast<SharedTextureContext *>(context);
150151
wgpu::SharedTextureMemoryEndAccessState endState = {};
151152
ctx->sharedTextureMemory.EndAccess(ctx->texture, &endState);
152153
delete ctx;
153-
},
154-
new SharedTextureContext{memory, texture}
155-
);
156-
return result;
157-
}
154+
},
155+
new SharedTextureContext{memory, texture});
156+
return result;
157+
}
158158
if (!success) {
159-
return nullptr;
159+
return nullptr;
160160
}
161161
return nullptr;
162162
}

packages/skia/cpp/rnskia/DawnUtils.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ createDawnBackendContext(dawn::native::Instance *instance) {
9090
features.push_back(wgpu::FeatureName::SharedTextureMemoryIOSurface);
9191
}
9292
#else
93-
if (adapter.HasFeature(wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer)) {
93+
if (adapter.HasFeature(
94+
wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer)) {
9495
features.push_back(wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer);
9596
}
9697
#endif

packages/skia/ios/RNSkia-iOS/RNSkMetalCanvasProvider.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ class RNSkMetalCanvasProvider : public RNSkia::RNSkCanvasProvider {
3030

3131
private:
3232
std::shared_ptr<RNSkia::RNSkPlatformContext> _context;
33-
float _width = -1;
34-
float _height = -1;
33+
std::unique_ptr<RNSkia::WindowContext> _ctx = nullptr;
3534
#pragma clang diagnostic push
3635
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
3736
CAMetalLayer *_layer;

packages/skia/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm

+18-23
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,23 @@
3636
/**
3737
Returns the scaled width of the view
3838
*/
39-
float RNSkMetalCanvasProvider::getScaledWidth() { return _width; };
39+
float RNSkMetalCanvasProvider::getScaledWidth() {
40+
return _ctx ? _ctx->getWidth() : -1;
41+
};
4042

4143
/**
4244
Returns the scaled height of the view
4345
*/
44-
float RNSkMetalCanvasProvider::getScaledHeight() { return _height; };
46+
float RNSkMetalCanvasProvider::getScaledHeight() {
47+
return _ctx ? _ctx->getHeight() : -1;
48+
};
4549

4650
/**
4751
Render to a canvas
4852
*/
4953
bool RNSkMetalCanvasProvider::renderToCanvas(
5054
const std::function<void(SkCanvas *)> &cb) {
51-
if (_width <= 0 || _height <= 0) {
55+
if (!_ctx) {
5256
return false;
5357
}
5458

@@ -72,33 +76,24 @@
7276
// rendering and not wait until later - we've seen some example of memory
7377
// usage growing very fast in the simulator without this.
7478
@autoreleasepool {
75-
id<CAMetalDrawable> currentDrawable = [_layer nextDrawable];
76-
if (currentDrawable == nullptr) {
77-
return false;
78-
}
79-
#if defined(SK_GRAPHITE)
80-
auto ctx = RNSkia::DawnContext::getInstance().MakeWindow(
81-
(__bridge void *)_layer, _width, _height);
82-
#else
83-
auto ctx = MetalContext::getInstance().MakeWindow(_layer, _width, _height);
84-
#endif
85-
auto skSurface = ctx->getSurface();
86-
SkCanvas *canvas = skSurface->getCanvas();
79+
auto surface = _ctx->getSurface();
80+
auto canvas = surface->getCanvas();
8781
cb(canvas);
88-
89-
if (auto dContext = GrAsDirectContext(skSurface->recordingContext())) {
90-
dContext->flushAndSubmit();
91-
}
92-
93-
ctx->present();
82+
_ctx->present();
9483
}
9584
return true;
9685
};
9786

9887
void RNSkMetalCanvasProvider::setSize(int width, int height) {
9988
_layer.frame = CGRectMake(0, 0, width, height);
100-
_width = width * _context->getPixelDensity();
101-
_height = height * _context->getPixelDensity();
89+
auto w = width * _context->getPixelDensity();
90+
auto h = height * _context->getPixelDensity();
91+
#if defined(SK_GRAPHITE)
92+
_ctx = RNSkia::DawnContext::getInstance().MakeWindow((__bridge void *)_layer,
93+
w, h);
94+
#else
95+
_ctx = MetalContext::getInstance().MakeWindow(_layer, w, h);
96+
#endif
10297
_requestRedraw();
10398
}
10499

packages/skia/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h

+22-8
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,19 @@
1111
#pragma clang diagnostic ignored "-Wdocumentation"
1212

1313
#import "include/core/SkCanvas.h"
14+
#import "include/core/SkColorSpace.h"
15+
1416
#import <CoreMedia/CMSampleBuffer.h>
1517
#import <CoreVideo/CVMetalTextureCache.h>
18+
19+
#import <include/gpu/ganesh/GrBackendSurface.h>
1620
#import <include/gpu/ganesh/GrDirectContext.h>
21+
#import <include/gpu/ganesh/SkImageGanesh.h>
22+
#import <include/gpu/ganesh/SkSurfaceGanesh.h>
23+
#import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
24+
#import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
25+
#import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
26+
#import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
1727

1828
#pragma clang diagnostic pop
1929

@@ -26,9 +36,6 @@ class SkiaMetalSurfaceFactory {
2636
friend class IOSSkiaContext;
2737

2838
public:
29-
static sk_sp<SkSurface> makeWindowedSurface(SkiaMetalContext *context,
30-
id<MTLTexture> texture, int width,
31-
int height);
3239
static sk_sp<SkSurface> makeOffscreenSurface(id<MTLDevice> device,
3340
SkiaMetalContext *context,
3441
int width, int height);
@@ -76,9 +83,16 @@ class IOSSkiaContext : public RNSkia::WindowContext {
7683
}
7784

7885
// Get the texture from the drawable
79-
_skSurface = SkiaMetalSurfaceFactory::makeWindowedSurface(
80-
_context, _currentDrawable.texture, _layer.drawableSize.width,
81-
_layer.drawableSize.height);
86+
GrMtlTextureInfo fbInfo;
87+
fbInfo.fTexture.retain((__bridge void *)_currentDrawable.texture);
88+
89+
GrBackendRenderTarget backendRT = GrBackendRenderTargets::MakeMtl(
90+
_layer.drawableSize.width, _layer.drawableSize.height, fbInfo);
91+
92+
_skSurface = SkSurfaces::WrapBackendRenderTarget(
93+
_context->skContext.get(), backendRT, kTopLeft_GrSurfaceOrigin,
94+
kBGRA_8888_SkColorType, nullptr, nullptr);
95+
8296
return _skSurface;
8397
}
8498

@@ -95,9 +109,9 @@ class IOSSkiaContext : public RNSkia::WindowContext {
95109

96110
void resize(int width, int height) override { _skSurface = nullptr; }
97111

98-
int getWidth() override { return _layer.frame.size.width; };
112+
int getWidth() override { return _layer.frame.size.width * _layer.contentsScale; };
99113

100-
int getHeight() override { return _layer.frame.size.height; };
114+
int getHeight() override { return _layer.frame.size.height * _layer.contentsScale; };
101115

102116
private:
103117
SkiaMetalContext *_context;

packages/skia/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm

-20
Original file line numberDiff line numberDiff line change
@@ -46,26 +46,6 @@
4646
return std::make_unique<IOSSkiaContext>(context, texture, width, height);
4747
}
4848

49-
sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeWindowedSurface(
50-
SkiaMetalContext *context, id<MTLTexture> texture, int width, int height) {
51-
GrMtlTextureInfo fbInfo;
52-
fbInfo.fTexture.retain((__bridge void *)texture);
53-
54-
GrBackendRenderTarget backendRT =
55-
GrBackendRenderTargets::MakeMtl(width, height, fbInfo);
56-
57-
auto skSurface = SkSurfaces::WrapBackendRenderTarget(
58-
context->skContext.get(), backendRT, kTopLeft_GrSurfaceOrigin,
59-
kBGRA_8888_SkColorType, nullptr, nullptr);
60-
61-
if (skSurface == nullptr || skSurface->getCanvas() == nullptr) {
62-
RNSkia::RNSkLogger::logToConsole(
63-
"Skia surface could not be created from parameters.");
64-
return nullptr;
65-
}
66-
return skSurface;
67-
}
68-
6949
sk_sp<SkSurface> SkiaMetalSurfaceFactory::makeOffscreenSurface(
7050
id<MTLDevice> device, SkiaMetalContext *context, int width, int height) {
7151

0 commit comments

Comments
 (0)