Skip to content

Commit

Permalink
perf(native): don't double encode assets (#2996)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett committed Sep 12, 2023
1 parent 587e034 commit 60b7e09
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 37 deletions.
2 changes: 1 addition & 1 deletion packages/fiber/src/native/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ const CanvasImpl = /*#__PURE__*/ React.forwardRef<View, Props>(

return (
<View {...props} ref={viewRef} onLayout={onLayout} style={{ flex: 1, ...style }} {...bind}>
{width > 0 && <GLView onContextCreate={onContextCreate} style={StyleSheet.absoluteFill} />}
{width > 0 && <GLView msaaSamples={0} onContextCreate={onContextCreate} style={StyleSheet.absoluteFill} />}
</View>
)
},
Expand Down
63 changes: 27 additions & 36 deletions packages/fiber/src/native/polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ export function polyfills() {
})
}

async function getAsset(input: string | number): Promise<Asset> {
async function getAsset(input: string | number): Promise<string> {
if (typeof input === 'string') {
// Point to storage if preceded with fs path
if (input.startsWith('file:')) return { localUri: input } as Asset
// Don't process storage or data uris
if (input.startsWith('file:') || input.startsWith('data:')) return input

// Unpack Blobs from react-native BlobManager
if (input.startsWith('blob:')) {
Expand All @@ -56,33 +56,23 @@ export function polyfills() {
reader.readAsText(blob)
})

input = `data:${blob.type};base64,${data}`
}

// Create safe URI for JSI
if (input.startsWith('data:')) {
const [header, data] = input.split(',')
const [, type] = header.split('/')

const localUri = fs.cacheDirectory + uuidv4() + `.${type}`
await fs.writeAsStringAsync(localUri, data, { encoding: fs.EncodingType.Base64 })

return { localUri } as Asset
return `data:${blob.type};base64,${data}`
}
}

// Download bundler module or external URL
const asset = Asset.fromModule(input)
const asset = await Asset.fromModule(input).downloadAsync()
let uri = asset.localUri || asset.uri

// Unpack assets in Android Release Mode
if (!asset.uri.includes(':')) {
const localUri = `${fs.cacheDirectory}ExponentAsset-${asset.hash}.${asset.type}`
await fs.copyAsync({ from: asset.uri, to: localUri })
return { localUri } as Asset
if (!uri.includes(':')) {
const file = `${fs.cacheDirectory}ExponentAsset-${asset.hash}.${asset.type}`
const stats = await fs.getInfoAsync(file, { size: false })
if (!stats.exists) await fs.copyAsync({ from: uri, to: file })
uri = file
}

// Otherwise, resolve from registry
return asset.downloadAsync()
return uri
}

// Don't pre-process urls, let expo-asset generate an absolute URL
Expand All @@ -96,21 +86,24 @@ export function polyfills() {
const texture = new THREE.Texture()

getAsset(url)
.then(async (asset: Asset) => {
const uri = asset.localUri || asset.uri

if (!asset.width || !asset.height) {
const { width, height } = await new Promise<{ width: number; height: number }>((res, rej) =>
Image.getSize(uri, (width, height) => res({ width, height }), rej),
)
asset.width = width
asset.height = height
.then(async (uri) => {
// Create safe URI for JSI
if (uri.startsWith('data:')) {
const [header, data] = uri.split(',')
const [, type] = header.split('/')

uri = fs.cacheDirectory + uuidv4() + `.${type}`
await fs.writeAsStringAsync(uri, data, { encoding: fs.EncodingType.Base64 })
}

const { width, height } = await new Promise<{ width: number; height: number }>((res, rej) =>
Image.getSize(uri, (width, height) => res({ width, height }), rej),
)

texture.image = {
data: { localUri: uri },
width: asset.width,
height: asset.height,
width,
height,
}
texture.flipY = true
texture.unpackAlignment = 1
Expand All @@ -134,9 +127,7 @@ export function polyfills() {
const request = new XMLHttpRequest()

getAsset(url)
.then(async (asset) => {
let uri = asset.localUri || asset.uri

.then(async (uri) => {
// Make FS paths web-safe
if (uri.startsWith('file://')) {
const data = await fs.readAsStringAsync(uri, { encoding: fs.EncodingType.Base64 })
Expand Down

0 comments on commit 60b7e09

Please sign in to comment.