Skip to content

Commit

Permalink
Merge branch 'main' into chore/typegpu-0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
iwoplaza authored Nov 4, 2024
2 parents d249abf + 625a01e commit 5f59c2c
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 265 deletions.
4 changes: 2 additions & 2 deletions apps/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ PODS:
- React-debug
- react-native-safe-area-context (4.11.0):
- React-Core
- react-native-wgpu (0.1.18):
- react-native-wgpu (0.1.19):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1528,7 +1528,7 @@ SPEC CHECKSUMS:
React-logger: 29fa3e048f5f67fe396bc08af7606426d9bd7b5d
React-Mapbuffer: bf56147c9775491e53122a94c423ac201417e326
react-native-safe-area-context: 851c62c48dce80ccaa5637b6aa5991a1bc36eca9
react-native-wgpu: 0f842ae9566fdf3b6ff05034bf9cbe99e90c2b5e
react-native-wgpu: 5fd8cb5fd7bd00c88831d29438697d897fb680e8
React-nativeconfig: 9f223cd321823afdecf59ed00861ab2d69ee0fc1
React-NativeModulesApple: ff7efaff7098639db5631236cfd91d60abff04c0
React-perflogger: 32ed45d9cee02cf6639acae34251590dccd30994
Expand Down
2 changes: 1 addition & 1 deletion apps/example/src/Cube/Cube.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export function Cube() {

return (
<View style={style.container}>
<Canvas ref={ref} style={style.webgpu} androidTransparency />
<Canvas ref={ref} style={style.webgpu} transparent />
</View>
);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/example/src/GradientTiles/GradientTiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function GradientTiles() {

return (
<View style={style.container}>
<Canvas ref={ref} style={style.webgpu} androidTransparency />
<Canvas ref={ref} style={style.webgpu} transparent />
<View style={style.controls}>
<View style={style.buttonRow}>
<Text style={style.spanText}>span x: </Text>
Expand Down
71 changes: 38 additions & 33 deletions apps/example/src/Resize/Resize.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
import React, { useEffect, useRef } from "react";
import { Animated, Dimensions, PixelRatio, View } from "react-native";
import React, { useEffect } from "react";
import { Dimensions, PixelRatio, View } from "react-native";
import { Canvas } from "react-native-wgpu";
import Animated, {
cancelAnimation,
Easing,
useAnimatedStyle,
useDerivedValue,
useSharedValue,
withRepeat,
withTiming,
} from "react-native-reanimated";

import { redFragWGSL, triangleVertWGSL } from "../Triangle/triangle";
import { useWebGPU } from "../components/useWebGPU";

const window = Dimensions.get("window");
const win = Dimensions.get("window");

export const Resize = () => {
const width = useRef(new Animated.Value(20));
const widthRef = useRef(20);
export const useLoop = ({ duration }: { duration: number }) => {
const progress = useSharedValue(0);
useEffect(() => {
width.current.addListener(({ value }) => {
widthRef.current = value;
});
}, []);
progress.value = withRepeat(
withTiming(1, { duration, easing: Easing.inOut(Easing.ease) }),
-1,
true,
);
return () => {
cancelAnimation(progress);
};
}, [duration, progress]);
return progress;
};

export const Resize = () => {
const progress = useLoop({ duration: 4000 });
const width = useDerivedValue(() => {
return 20 + progress.value * (win.width - 20);
});
const ref = useWebGPU(({ context, device, presentationFormat, canvas }) => {
const sampleCount = 4;
const pipeline = device.createRenderPipeline({
Expand Down Expand Up @@ -75,12 +96,13 @@ export const Resize = () => {
}
if (renderTargetView) {
const commandEncoder = device.createCommandEncoder();
const a = 0.7;
const renderPassDescriptor: GPURenderPassDescriptor = {
colorAttachments: [
{
view: renderTargetView,
resolveTarget: context.getCurrentTexture().createView(),
clearValue: [0.5, 0.5, 0.5, 1],
clearValue: [a, a, a, a],
loadOp: "clear",
storeOp: "store",
},
Expand All @@ -97,30 +119,13 @@ export const Resize = () => {
}
};
});

useEffect(() => {
Animated.loop(
Animated.sequence([
Animated.timing(width.current, {
toValue: window.width,
duration: 4000,
useNativeDriver: false,
}),
Animated.timing(width.current, {
toValue: 20,
duration: 4000,
useNativeDriver: false,
}),
]),
).start();
}, []);

const style = useAnimatedStyle(() => {
return { width: width.value, flex: 1, backgroundColor: "cyan" };
});
return (
<View style={{ flex: 1, alignItems: "center" }}>
<Animated.View
style={{ width: width.current, flex: 1, backgroundColor: "red" }}
>
<Canvas ref={ref} style={{ flex: 1 }} />
<Animated.View style={style}>
<Canvas ref={ref} style={{ flex: 0.5 }} transparent />
</Animated.View>
</View>
);
Expand Down
6 changes: 1 addition & 5 deletions apps/example/src/Triangle/HelloTriangle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,7 @@ export function HelloTriangle() {
return (
<View style={style.container}>
<View style={{ flex: 1, backgroundColor: "#3498db" }} />
<Canvas
ref={ref}
style={StyleSheet.absoluteFill}
androidTransparency={true}
/>
<Canvas ref={ref} style={StyleSheet.absoluteFill} transparent />
</View>
);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/example/src/Triangle/HelloTriangleMSAA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function HelloTriangleMSAA() {

return (
<View style={style.container}>
<Canvas ref={ref} style={style.webgpu} />
<Canvas ref={ref} style={style.webgpu} transparent />
</View>
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/webgpu/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static def findNodeModules(baseDir) {
basePath = basePath.getParent()
}

throw new GradleException("react-native-filament: Failed to find node_modules/ path!")
throw new GradleException("react-native-wgpu: Failed to find node_modules/ path!")
}

def nodeModules = findNodeModules(projectDir)
Expand Down
74 changes: 41 additions & 33 deletions packages/webgpu/android/src/main/java/com/webgpu/WebGPUAHBView.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.util.LinkedList;
import java.util.Queue;

@SuppressLint("ViewConstructor")
@RequiresApi(api = Build.VERSION_CODES.Q)
public class WebGPUAHBView extends View {
public class WebGPUAHBView extends View implements ImageReader.OnImageAvailableListener {

private ImageReader mReader;

private final Queue<ImageReader> mImageReaders = new LinkedList<>();
private Bitmap mBitmap = null;

private final Matrix matrix = new Matrix();
Expand All @@ -34,48 +32,58 @@ public WebGPUAHBView(Context context, WebGPUAPI api) {
mApi = api;
}

private ImageReader createReader() {
ImageReader reader = ImageReader.newInstance(getWidth(), getHeight(), PixelFormat.RGBA_8888, 2, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE |
HardwareBuffer.USAGE_GPU_COLOR_OUTPUT);
reader.setOnImageAvailableListener(this, null);
return reader;
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
long usage = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE |
HardwareBuffer.USAGE_GPU_COLOR_OUTPUT;
ImageReader imageReader = ImageReader.newInstance(getWidth(), getHeight(), PixelFormat.RGBA_8888, 2, usage);
if (mImageReaders.isEmpty()) {
mApi.surfaceCreated(imageReader.getSurface());
if (mReader == null) {
mReader = createReader();
mApi.surfaceCreated(mReader.getSurface());
} else {
mApi.surfaceChanged(imageReader.getSurface());
mApi.surfaceChanged(mReader.getSurface());
}
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireLatestImage()) {
if (image != null) {
HardwareBuffer hb = image.getHardwareBuffer();
if (hb != null) {
Bitmap bitmap = Bitmap.wrapHardwareBuffer(hb, null);
if (bitmap != null) {
mBitmap = bitmap;
hb.close();
invalidate();
ImageReader imageReader = mImageReaders.poll();
ImageReader ir;
while((ir = mImageReaders.poll()) != null) {
ir.close();
}
mImageReaders.add(imageReader);
}
}
}

@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireLatestImage()) {
if (image != null) {
HardwareBuffer hb = image.getHardwareBuffer();
if (hb != null) {
Bitmap bitmap = Bitmap.wrapHardwareBuffer(hb, null);
if (bitmap != null) {
mBitmap = bitmap;
hb.close();
invalidate();
}
}
}
}, null);
mImageReaders.add(imageReader);
}
}

@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null) {
float viewWidth = getWidth();
float viewHeight = getHeight();
float bitmapWidth = mBitmap.getWidth();
float bitmapHeight = mBitmap.getHeight();

// Calculate the scale factors
float scaleX = viewWidth / bitmapWidth;
float scaleY = viewHeight / bitmapHeight;

// Reset the matrix and apply scaling
matrix.reset();
matrix.setScale(scaleX, scaleY);

canvas.drawBitmap(mBitmap, matrix, null);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

@SuppressLint("ViewConstructor")
@RequiresApi(api = Build.VERSION_CODES.Q)
public class SurfaceView2 extends SurfaceView implements SurfaceHolder.Callback {
public class WebGPUSurfaceViewWithSC extends SurfaceView implements SurfaceHolder.Callback {

WebGPUAPI mApi;
SurfaceControl mSurfaceControl;
Surface mSurface;

public SurfaceView2(Context context, WebGPUAPI api) {
public WebGPUSurfaceViewWithSC(Context context, WebGPUAPI api) {
super(context);
mApi = api;
getHolder().addCallback(this);
Expand All @@ -48,7 +48,7 @@ public void surfaceCreated(@NonNull SurfaceHolder holder) {
} else {
SurfaceControl.Builder scb = new SurfaceControl.Builder();
scb.setName("WebGPUView");
scb.setOpaque(false);
scb.setOpaque(true);
scb.setBufferSize(getWidth(), getHeight());
scb.setParent(getSurfaceControl());
scb.setFormat(PixelFormat.RGBA_8888);
Expand Down
57 changes: 15 additions & 42 deletions packages/webgpu/android/src/main/java/com/webgpu/WebGPUView.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,17 @@
import android.view.Surface;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringDef;

import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.views.view.ReactViewGroup;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class WebGPUView extends ReactViewGroup implements WebGPUAPI {

public static final String SURFACE_VIEW = "SurfaceView";
public static final String TEXTURE_VIEW = "TextureView";
public static final String HARDWARE_BUFFER = "HardwareBuffer";
public static final String SURFACE_VIEW2 = "SurfaceView2";

@Retention(RetentionPolicy.SOURCE)
@StringDef({
SURFACE_VIEW,
TEXTURE_VIEW,
HARDWARE_BUFFER,
SURFACE_VIEW2
})
public @interface ViewType {}

private int mContextId;
private @ViewType String mName = null;
private boolean mTransparent = false;
private WebGPUModule mModule;
private View mView;
private View mView = null;

WebGPUView(Context context) {
super(context);
Expand All @@ -51,28 +31,21 @@ public void setContextId(int contextId) {
mContextId = contextId;
}

public void setView(@NonNull @ViewType String name) {
public void setTransparent(boolean value) {
Context ctx = getContext();
if (mName == null || !mName.equals(name)) {
removeView(mView);
mName = name;
switch (name) {
case TEXTURE_VIEW -> mView = new WebGPUTextureView(ctx, this);
case HARDWARE_BUFFER -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mView = new WebGPUAHBView(ctx, this);
} else {
throw new RuntimeException("HardwareBuffer Canvas implementation is only available on API Level 29 and above");
}
}
case SURFACE_VIEW2 -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mView = new SurfaceView2(ctx, this);
} else {
throw new RuntimeException("HardwareBuffer Canvas implementation is only available on API Level 29 and above");
}
if (value != mTransparent || mView == null) {
if (mView != null) {
removeView(mView);
}
mTransparent = value;
if (mTransparent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mView = new WebGPUAHBView(ctx, this);
} else {
mView = new WebGPUTextureView(ctx, this);
}
default -> mView = new WebGPUSurfaceView(ctx, this);
} else {
mView = new WebGPUSurfaceView(ctx, this);
}
addView(mView);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public WebGPUView createViewInstance(@NonNull ThemedReactContext context) {
}

@Override
@ReactProp(name = "androidView")
public void setAndroidView(WebGPUView view, @Nullable String value) {
view.setView(value == null ? WebGPUView.SURFACE_VIEW : value);
@ReactProp(name = "transparent")
public void setTransparent(WebGPUView view, boolean value) {
view.setTransparent(value);
}

@Override
Expand Down
Loading

0 comments on commit 5f59c2c

Please sign in to comment.