乐趣区

关于c:C速成指南从入门到进阶实战WPF与Unity3D开发

download:C# 速成指南:从入门到进阶,实战 WPF 与 Unity3D 开发

备链:https://www.97yrbl.com/t-1374.html

新的计划

咱们奇妙地将 FFi 计划与外接纹理计划组合,解决了一系列业务痛点。

FFI
正如结尾说的那些问题,Texture 计划有些做不到的事件,这须要其余计划来互补,这其中外围须要的就是 ui.Image。咱们把 native 内存地址、长度等信息传递给 flutter 侧,用于生成 ui.Image。

首先 native 侧先获取必要的参数(以 iOS 为例):

_rowBytes = CGImageGetBytesPerRow(cgImage);

CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImage);
CFDataRef rawDataRef = CGDataProviderCopyData(dataProvider);
_handle = (long)CFDataGetBytePtr(rawDataRef);

NSData *data = CFBridgingRelease(rawDataRef);
self.data = data;
_length = data.length;
dart 侧拿到后,@override
  FutureOr<ImageInfo> createImageInfo(Map map) {Completer<ImageInfo> completer = Completer<ImageInfo>();
int handle = map['handle'];
int length = map['length'];
int width = map['width'];
int height = map['height'];
int rowBytes = map['rowBytes'];
ui.PixelFormat pixelFormat =
    ui.PixelFormat.values[map['flutterPixelFormat'] ?? 0];
Pointer<Uint8> pointer = Pointer<Uint8>.fromAddress(handle);
Uint8List pixels = pointer.asTypedList(length);
ui.decodeImageFromPixels(pixels, width, height, pixelFormat,
    (ui.Image image) {ImageInfo imageInfo = ImageInfo(image: image);
  completer.complete(imageInfo);
  // 开释 native 内存
  PowerImageLoader.instance.releaseImageRequest(options);
}, rowBytes: rowBytes);
return completer.future;
  }

咱们能够通过 ffi 拿到 native 内存,从而生成 ui.Image。这里有个问题,尽管通过 ffi 能间接获取 native 内存,然而因为 decodeImageFromPixels 会有内存拷贝,在拷贝解码后的图片数据时,内存峰值会更加重大。

这里有两个优化方向:

解码前的图片数据给 flutter,由 flutter 提供的解码器解码,从而削减内存拷贝峰值;
与 flutter 官网探讨,尝试从外部缩小这次内存拷贝。
FFI 这种形式适宜轻度应用、非凡场景应用,反对这种形式能够解决无奈获取 ui.Image 的问题,也能够在模拟器上展现图片(flutter <= 1.23.0-18.1.pre),并且图片缓存将齐全交给 ImageCache 治理。

Texture
Texture 计划与原生联合有一些难度,这里波及到没有 ui.Image 只有 textureId。这里有几个问题须要解决:

问题一:Image Widget 须要 ui.Image 去 build RawImage 从而绘制,这在本文后面的 Flutter 原生计划介绍中也提到了。

问题二:ImageCache 依赖 ImageInfoui.Image 的宽高进行 cache 大小计算以及缓存前的校验。

问题三:native 侧 texture 生命周期治理

都有解决方案:

问题一:通过自定义 Image 解决,透出 imageBuilder 来让内部自定义图片 widget

问题二:为 Texture 自定义 ui.image,如下:

import 'dart:typed_data';
import 'dart:ui' as ui show Image;
import 'dart:ui';

class TextureImage implements ui.Image {
  int _width;
  int _height;
  int textureId;
  TextureImage(this.textureId, int width, int height)
      : _width = width,
        _height = height;

  @override
  void dispose() {// TODO: implement dispose}

  @override
  int get height => _height;

  @override
  Future<ByteData> toByteData({ImageByteFormat format = ImageByteFormat.rawRgba}) {
    // TODO: implement toByteData
    throw UnimplementedError();}
退出移动版