Skip to content

Commit

Permalink
Update CameraMatrix directly
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Jul 25, 2024
1 parent 85d206c commit 7ad7993
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 26 deletions.
1 change: 1 addition & 0 deletions package/src/Camera.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ export class Camera extends React.PureComponent<CameraProps, CameraState> {
<SkiaCameraCanvas
style={styles.customPreviewView}
offscreenTextures={frameProcessor.offscreenTextures}
cameraMatrix={frameProcessor.cameraMatrix}
resizeMode={props.resizeMode}
/>
)}
Expand Down
8 changes: 8 additions & 0 deletions package/src/skia/SkiaCameraCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ISharedValue } from 'react-native-worklets-core'
import type { SkImage } from '@shopify/react-native-skia'
import { ReanimatedProxy } from '../dependencies/ReanimatedProxy'
import { SkiaProxy } from '../dependencies/SkiaProxy'
import type { CameraMatrix } from '../types/CameraMatrix'

interface SkiaCameraCanvasProps extends ViewProps {
/**
Expand All @@ -13,6 +14,13 @@ interface SkiaCameraCanvasProps extends ViewProps {
* This view will always pop the latest Texture from this queue and render it.
*/
offscreenTextures: ISharedValue<SkImage[]>
/**
* The Matrix created by the Skia Frame Processor.
*
* While the Skia Frame Processor populates the Matrix's width and orientation data,
* the `<SkiaCameraCanvas>` populates it's `viewWidth` and `viewHeight` properties.
*/
cameraMatrix: ISharedValue<CameraMatrix>
/**
* The resize mode to use for displaying the feed
*/
Expand Down
40 changes: 14 additions & 26 deletions package/src/skia/useSkiaFrameProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function relativeTo(a: Orientation, b: Orientation): Orientation {
* Counter-rotates the {@linkcode canvas} by the {@linkcode frame}'s {@linkcode Frame.orientation orientation}
* to ensure the Frame will be drawn upright.
*/
function withRotatedFrame(frame: Frame, canvas: SkCanvas, previewOrientation: Orientation, func: () => void): void {
function withRotatedFrame(frame: Frame, canvas: SkCanvas, previewOrientation: Orientation, func: () => void): CameraMatrix {
'worklet'

// 1. save current translation matrix
Expand Down Expand Up @@ -115,6 +115,14 @@ function withRotatedFrame(frame: Frame, canvas: SkCanvas, previewOrientation: Or

// 3. call actual processing code
func()

// 5. Return a Matrix used to translate from view to camera points
return {
width: frame.width,
height: frame.height,
isMirrored: frame.isMirrored,
orientation: orientation,
}
} finally {
// 4. restore matrix again to original base
canvas.restore()
Expand Down Expand Up @@ -272,26 +280,6 @@ export function createSkiaFrameProcessor(
return (frame as FrameInternal).withBaseClass(canvasProxy)
}

const updateCameraMatrix = (frame: Frame): void => {
'worklet'

const currentMatrix = cameraMatrix.value
if (
currentMatrix.width !== frame.width ||
currentMatrix.height !== frame.height ||
currentMatrix.isMirrored !== frame.isMirrored ||
currentMatrix.orientation !== frame.orientation
) {
// Update Matrix
cameraMatrix.value = {
width: frame.width,
height: frame.height,
isMirrored: frame.isMirrored,
orientation: frame.orientation,
}
}
}

return {
frameProcessor: withFrameRefCounting((frame) => {
'worklet'
Expand All @@ -309,13 +297,16 @@ export function createSkiaFrameProcessor(
canvas.clear(black)

// 4. rotate the frame properly to make sure it's upright
withRotatedFrame(frame, canvas, previewOrientation.value, () => {
const matrix = withRotatedFrame(frame, canvas, previewOrientation.value, () => {
// 5. Run any user drawing operations
frameProcessor(drawableFrame)
})

// 6. Flush draw operations and submit to GPU
// 5. Flush draw operations and submit to GPU
surface.flush()

// 6. Update the Camera Matrix
cameraMatrix.value = matrix
} finally {
// 7. Delete the SkImage/Texture that holds the Frame
drawableFrame.dispose()
Expand All @@ -334,9 +325,6 @@ export function createSkiaFrameProcessor(
if (texture == null) break
texture.dispose()
}

// 10. After rendering, update the Camera Matrix used for view -> camera conversions
updateCameraMatrix(frame)
}),
type: 'drawable-skia',
offscreenTextures: offscreenTextures,
Expand Down

0 comments on commit 7ad7993

Please sign in to comment.