diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatARTSurfaceViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatARTSurfaceViewManager.java new file mode 100644 index 000000000..f05ad7bd7 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatARTSurfaceViewManager.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.flat; + +import android.graphics.Bitmap; + +import com.facebook.csslayout.CSSMeasureMode; +import com.facebook.csslayout.CSSNode; +import com.facebook.csslayout.MeasureOutput; +import com.facebook.react.uimanager.BaseViewManager; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.views.art.ARTSurfaceView; + +/* protected */ class FlatARTSurfaceViewManager extends + BaseViewManager { + + private static final String REACT_CLASS = "ARTSurfaceView"; + + private static final CSSNode.MeasureFunction MEASURE_FUNCTION = new CSSNode.MeasureFunction() { + @Override + public void measure( + CSSNode node, + float width, + CSSMeasureMode widthMode, + float height, + CSSMeasureMode heightMode, + MeasureOutput measureOutput) { + throw new IllegalStateException("SurfaceView should have explicit width and height set"); + } + }; + + @Override + public String getName() { + return REACT_CLASS; + } + + @Override + public FlatARTSurfaceViewShadowNode createShadowNodeInstance() { + FlatARTSurfaceViewShadowNode node = new FlatARTSurfaceViewShadowNode(); + node.setMeasureFunction(MEASURE_FUNCTION); + return node; + } + + @Override + public Class getShadowNodeClass() { + return FlatARTSurfaceViewShadowNode.class; + } + + @Override + protected ARTSurfaceView createViewInstance(ThemedReactContext reactContext) { + return new ARTSurfaceView(reactContext); + } + + @Override + public void updateExtraData(ARTSurfaceView root, Object extraData) { + root.setBitmap((Bitmap) extraData); + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatARTSurfaceViewShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatARTSurfaceViewShadowNode.java new file mode 100644 index 000000000..4b139f76b --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatARTSurfaceViewShadowNode.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.flat; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; + +import com.facebook.react.uimanager.UIViewOperationQueue; +import com.facebook.react.views.art.ARTVirtualNode; + +/* package */ class FlatARTSurfaceViewShadowNode extends FlatShadowNode implements AndroidView { + private boolean mPaddingChanged = false; + + /* package */ FlatARTSurfaceViewShadowNode() { + forceMountToView(); + forceMountChildrenToView(); + } + + @Override + public boolean isVirtual() { + return false; + } + + @Override + public boolean isVirtualAnchor() { + return true; + } + + @Override + public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) { + super.onCollectExtraUpdates(uiUpdater); + uiUpdater.enqueueUpdateExtraData(getReactTag(), drawOutput()); + } + + private Object drawOutput() { + // TODO(7255985): Use TextureView and pass Surface from the view to draw on it asynchronously + // instead of passing the bitmap (which is inefficient especially in terms of memory usage) + Bitmap bitmap = Bitmap.createBitmap( + (int) getLayoutWidth(), + (int) getLayoutHeight(), + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); + for (int i = 0; i < getChildCount(); i++) { + ARTVirtualNode child = (ARTVirtualNode) getChildAt(i); + child.draw(canvas, paint, 1f); + child.markUpdateSeen(); + } + return bitmap; + } + + @Override + public boolean needsCustomLayoutForChildren() { + return false; + } + + @Override + public boolean isPaddingChanged() { + return mPaddingChanged; + } + + @Override + public void resetPaddingChanged() { + mPaddingChanged = false; + } + + @Override + public void setPadding(int spacingType, float padding) { + if (getPadding().set(spacingType, padding)) { + mPaddingChanged = true; + dirty(); + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java index c775c3502..2dc0ff76e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java @@ -226,6 +226,13 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; } } + @Override + protected void markUpdated() { + super.markUpdated(); + mIsUpdated = true; + invalidate(); + } + /* package */ final boolean isUpdated() { return mIsUpdated; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java index de57540da..d3ba4bbd6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java @@ -58,6 +58,7 @@ public class FlatUIImplementation extends UIImplementation { viewManagers.add(new RCTImageViewManager()); viewManagers.add(new RCTTextInputManager()); viewManagers.add(new RCTViewPagerManager()); + viewManagers.add(new FlatARTSurfaceViewManager()); viewManagers.add(new RCTModalHostManager(reactContext)); ViewManagerRegistry viewManagerRegistry = new ViewManagerRegistry(viewManagers);