Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Flutter External Texture Based On Share Texture Underlying Share Con… #11276

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ FILE: ../../../flutter/shell/platform/android/android_environment_gl.h
FILE: ../../../flutter/shell/platform/android/android_exports.lst
FILE: ../../../flutter/shell/platform/android/android_external_texture_gl.cc
FILE: ../../../flutter/shell/platform/android/android_external_texture_gl.h
FILE: ../../../flutter/shell/platform/android/android_external_texture_gl_share_context.cc
FILE: ../../../flutter/shell/platform/android/android_external_texture_gl_share_context.h
FILE: ../../../flutter/shell/platform/android/android_native_window.cc
FILE: ../../../flutter/shell/platform/android/android_native_window.h
FILE: ../../../flutter/shell/platform/android/android_shell_holder.cc
Expand Down Expand Up @@ -775,6 +777,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_i
FILE: ../../../flutter/shell/platform/darwin/ios/framework/module.modulemap
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_gl.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_gl.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_gl_share_context.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_gl_share_context.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_gl_context.h
FILE: ../../../flutter/shell/platform/darwin/ios/ios_gl_context.mm
FILE: ../../../flutter/shell/platform/darwin/ios/ios_gl_render_target.h
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ shared_library("flutter_shell_native") {
"android_environment_gl.h",
"android_external_texture_gl.cc",
"android_external_texture_gl.h",
"android_external_texture_gl_share_context.cc",
"android_external_texture_gl_share_context.h",
"android_native_window.cc",
"android_native_window.h",
"android_shell_holder.cc",
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/android_context_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,8 @@ bool AndroidContextGL::Resize(const SkISize& size) {
return true;
}

EGLContext AndroidContextGL::GetShareContext() {
return context_;
}

} // namespace flutter
2 changes: 2 additions & 0 deletions shell/platform/android/android_context_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class AndroidContextGL : public fml::RefCountedThreadSafe<AndroidContextGL> {

bool Resize(const SkISize& size);

EGLContext GetShareContext();

private:
fml::RefPtr<AndroidEnvironmentGL> environment_;
fml::RefPtr<AndroidNativeWindow> window_;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/android/android_external_texture_gl_share_context.h"

#include <GLES/glext.h>

#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"

namespace flutter {

AndroidExternalTextureShareContext::AndroidExternalTextureShareContext(
int64_t id,
int64_t shareTextureID)
: Texture(id), texture_id_(shareTextureID) {}

AndroidExternalTextureShareContext::~AndroidExternalTextureShareContext() {}

void AndroidExternalTextureShareContext::OnGrContextCreated() {}

void AndroidExternalTextureShareContext::MarkNewFrameAvailable() {}

void AndroidExternalTextureShareContext::Paint(SkCanvas& canvas,
const SkRect& bounds,
bool freeze,
GrContext* context) {
GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_id_,
GL_RGBA8_OES};

textureInfo.fTarget = GL_TEXTURE_2D;
transform.setIdentity();

GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo);
sk_sp<SkImage> image = SkImage::MakeFromTexture(
canvas.getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
if (image) {
SkAutoCanvasRestore autoRestore(&canvas, true);
canvas.translate(bounds.x(), bounds.y());
canvas.scale(bounds.width(), bounds.height());
if (!transform.isIdentity()) {
SkMatrix transformAroundCenter(transform);

transformAroundCenter.preTranslate(-0.5, -0.5);
transformAroundCenter.postScale(1, -1);
transformAroundCenter.postTranslate(0.5, 0.5);
canvas.concat(transformAroundCenter);
}
canvas.drawImage(image, 0, 0);
}
}

void AndroidExternalTextureShareContext::OnGrContextDestroyed() {}
} // namespace flutter
43 changes: 43 additions & 0 deletions shell/platform/android/android_external_texture_gl_share_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_EXTERNAL_TEXTURE_SHARE_CONTEXT_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_EXTERNAL_TEXTURE_SHARE_CONTEXT_H_

#include <GLES/gl.h>
#include "flutter/flow/texture.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"

namespace flutter {

class AndroidExternalTextureShareContext : public flutter::Texture {
public:
AndroidExternalTextureShareContext(int64_t id, int64_t shareTextureID);

~AndroidExternalTextureShareContext() override;

void Paint(SkCanvas& canvas,
const SkRect& bounds,
bool freeze,
GrContext* context) override;

void OnGrContextCreated() override;

void OnGrContextDestroyed() override;

void MarkNewFrameAvailable() override;

private:
fml::jni::JavaObjectWeakGlobalRef surface_texture_;

GLuint texture_id_ = 0;

SkMatrix transform;

FML_DISALLOW_COPY_AND_ASSIGN(AndroidExternalTextureShareContext);
};

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_ANDROID_EXTERNAL_TEXTURE_GL_H_
3 changes: 3 additions & 0 deletions shell/platform/android/android_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <memory>

#include <EGL/egl.h>
#include "flutter/fml/macros.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
Expand Down Expand Up @@ -36,6 +37,8 @@ class AndroidSurface {
virtual bool ResourceContextClearCurrent() = 0;

virtual bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) = 0;

virtual EGLContext GetShareContext() = 0;
};

} // namespace flutter
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/android/android_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,7 @@ ExternalViewEmbedder* AndroidSurfaceGL::GetExternalViewEmbedder() {
return nullptr;
}

EGLContext AndroidSurfaceGL::GetShareContext() {
return offscreen_context_->GetShareContext();
}
} // namespace flutter
3 changes: 3 additions & 0 deletions shell/platform/android/android_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
// |AndroidSurface|
bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) override;

// |AndroidSurface|
EGLContext GetShareContext() override;

// |GPUSurfaceGLDelegate|
bool GLContextMakeCurrent() override;

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/android_surface_software.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,8 @@ bool AndroidSurfaceSoftware::SetNativeWindow(
return true;
}

EGLContext AndroidSurfaceSoftware::GetShareContext() {
return 0;
}

} // namespace flutter
3 changes: 3 additions & 0 deletions shell/platform/android/android_surface_software.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class AndroidSurfaceSoftware final : public AndroidSurface,
// |AndroidSurface|
bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) override;

// |AndroidSurface|
EGLContext GetShareContext() override;

// |GPUSurfaceSoftwareDelegate|
sk_sp<SkSurface> AcquireBackingStore(const SkISize& size) override;

Expand Down
18 changes: 18 additions & 0 deletions shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import android.support.annotation.UiThread;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.opengl.EGLContext;

import java.nio.ByteBuffer;
import java.util.HashSet;
Expand Down Expand Up @@ -555,6 +556,23 @@ public void registerTexture(long textureId, @NonNull SurfaceTexture surfaceTextu

private native void nativeRegisterTexture(long nativePlatformViewId, long textureId, @NonNull SurfaceTexture surfaceTexture);


@UiThread
public void registerShareTexture(long texIndex, long shareTextureId) {
ensureAttachedToNative();
nativeRegisterShareTexture(nativePlatformViewId, texIndex, shareTextureId);
}

private native void nativeRegisterShareTexture(long nativePlatformViewId, long texIndex, long shareTextureId);

@UiThread
public EGLContext getShareContext(long sdkInt) {
ensureAttachedToNative();
return nativeGetShareContext(nativePlatformViewId,sdkInt);
}

private native EGLContext nativeGetShareContext(long nativePlatformViewId,long sdkInt);

/**
* Call this method to inform Flutter that a texture previously registered with
* {@link #registerTexture(long, SurfaceTexture)} has a new frame available.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.Surface;
import android.opengl.EGLContext;

import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
Expand Down Expand Up @@ -120,6 +121,24 @@ public SurfaceTextureEntry createSurfaceTexture() {
return entry;
}

@Override
public TextureRegistry.ShareTextureEntry createShareTexture(long shareTextureID) {
final ShareTextureRegistryEntry entry = new ShareTextureRegistryEntry(nextTextureId.getAndIncrement(),shareTextureID);
Log.v(TAG, "New ShareTexture ID: " + entry.id());
registerShareTexture(entry.id(),shareTextureID);
return entry;
}

@Override
public void onShareFrameAvaliable(int textureIndex) {
markTextureFrameAvailable(textureIndex);
}

@Override
public EGLContext getShareContext(long sdkInt) {
return flutterJNI.getShareContext(sdkInt);
}

final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextureEntry {
private final long id;
@NonNull
Expand Down Expand Up @@ -178,7 +197,33 @@ public void release() {
released = true;
}
}
//------ END TextureRegistry IMPLEMENTATION ----

final class ShareTextureRegistryEntry implements TextureRegistry.ShareTextureEntry {
private final long id;
private final long textureID;
private boolean released;
ShareTextureRegistryEntry(long id, long shareTextureID) {
this.id = id;
this.textureID = shareTextureID;
}

@Override
public long id() {
return id;
}

@Override
public void release() {
if (released) {
return;
}
released = true;
unregisterTexture(id);
}
}

//------ END TextureRegistry IMPLEMENTATION ----


// TODO(mattcarroll): describe the native behavior that this invokes
public void surfaceCreated(@NonNull Surface surface) {
Expand Down Expand Up @@ -241,6 +286,10 @@ private void registerTexture(long textureId, @NonNull SurfaceTexture surfaceText
flutterJNI.registerTexture(textureId, surfaceTexture);
}

private void registerShareTexture(long textureId, long shareTextureID) {
flutterJNI.registerShareTexture(textureId, shareTextureID);
}

// TODO(mattcarroll): describe the native behavior that this invokes
private void markTextureFrameAvailable(long textureId) {
flutterJNI.markTextureFrameAvailable(textureId);
Expand Down
42 changes: 42 additions & 0 deletions shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.opengl.EGLContext;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
Expand Down Expand Up @@ -802,6 +803,23 @@ public TextureRegistry.SurfaceTextureEntry createSurfaceTexture() {
return entry;
}

@Override
public void onShareFrameAvaliable(int textureIndex) {
mNativeView.getFlutterJNI().markTextureFrameAvailable(textureIndex);
}

@Override
public TextureRegistry.ShareTextureEntry createShareTexture(long shareTextureID) {
final ShareTextureRegistryEntry entry = new ShareTextureRegistryEntry(nextTextureId.getAndIncrement(),shareTextureID);
mNativeView.getFlutterJNI().registerShareTexture(entry.id(),shareTextureID);
return entry;
}

@Override
public EGLContext getShareContext(long sdkInt) {
return mNativeView.getFlutterJNI().getShareContext(sdkInt);
}

final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextureEntry {
private final long id;
private final SurfaceTexture surfaceTexture;
Expand Down Expand Up @@ -865,4 +883,28 @@ public void release() {
mNativeView.getFlutterJNI().unregisterTexture(id);
}
}

final class ShareTextureRegistryEntry implements TextureRegistry.ShareTextureEntry {
private final long id;
private final long textureID;
private boolean released;
ShareTextureRegistryEntry(long id, long shareTextureID) {
this.id = id;
this.textureID = shareTextureID;
}

@Override
public long id() {
return id;
}

@Override
public void release() {
if (released) {
return;
}
released = true;
mNativeView.getFlutterJNI().unregisterTexture(id);
}
}
}
Loading