Commit 97997e5a authored by Vasiliy Telezhnikov's avatar Vasiliy Telezhnikov Committed by Chromium LUCI CQ

aw: Add overlays support to instrumentation apk

This CL implementats a new functor API to support SurfaceControl.

Bug: 1157096
Change-Id: I86a9b403b1d4eb160a4a81a5145153b73ee0558b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2615318Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843158}
parent 742358cf
...@@ -149,6 +149,8 @@ shared_library("libstandalonelibwebviewchromium") { ...@@ -149,6 +149,8 @@ shared_library("libstandalonelibwebviewchromium") {
"shell/src/draw_fn/allocator.h", "shell/src/draw_fn/allocator.h",
"shell/src/draw_fn/context_manager.cc", "shell/src/draw_fn/context_manager.cc",
"shell/src/draw_fn/context_manager.h", "shell/src/draw_fn/context_manager.h",
"shell/src/draw_fn/overlays_manager.cc",
"shell/src/draw_fn/overlays_manager.h",
] ]
ldflags = [ "-Wl,-shared,-Bsymbolic" ] ldflags = [ "-Wl,-shared,-Bsymbolic" ]
deps = [ deps = [
......
...@@ -41,6 +41,16 @@ AwDrawFnFunctionTable* GetDrawFnFunctionTable() { ...@@ -41,6 +41,16 @@ AwDrawFnFunctionTable* GetDrawFnFunctionTable() {
return &table; return &table;
} }
FunctorData::FunctorData() = default;
FunctorData::~FunctorData() = default;
FunctorData::FunctorData(FunctorData&&) = default;
FunctorData& FunctorData::operator=(FunctorData&&) = default;
FunctorData::FunctorData(int functor,
void* data,
AwDrawFnFunctorCallbacks* functor_callbacks)
: functor(functor), data(data), functor_callbacks(functor_callbacks) {}
// static // static
Allocator* Allocator::Get() { Allocator* Allocator::Get() {
static base::NoDestructor<Allocator> map; static base::NoDestructor<Allocator> map;
...@@ -54,11 +64,11 @@ int Allocator::allocate(void* data, ...@@ -54,11 +64,11 @@ int Allocator::allocate(void* data,
AwDrawFnFunctorCallbacks* functor_callbacks) { AwDrawFnFunctorCallbacks* functor_callbacks) {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
int functor = next_functor_++; int functor = next_functor_++;
map_.emplace(functor, FunctorData{functor, data, functor_callbacks}); map_.emplace(functor, FunctorData(functor, data, functor_callbacks));
return functor; return functor;
} }
FunctorData Allocator::get(int functor) { FunctorData& Allocator::get(int functor) {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
auto itr = map_.find(functor); auto itr = map_.find(functor);
DCHECK(itr != map_.end()); DCHECK(itr != map_.end());
......
...@@ -9,17 +9,30 @@ ...@@ -9,17 +9,30 @@
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "ui/gfx/android/android_surface_control_compat.h"
namespace draw_fn { namespace draw_fn {
AwDrawFnFunctionTable* GetDrawFnFunctionTable(); AwDrawFnFunctionTable* GetDrawFnFunctionTable();
struct FunctorData { struct FunctorData {
FunctorData();
FunctorData(int functor,
void* data,
AwDrawFnFunctorCallbacks* functor_callbacks);
~FunctorData();
FunctorData(FunctorData&&);
FunctorData& operator=(FunctorData&&);
FunctorData(const FunctorData&) = delete;
FunctorData& operator=(const FunctorData&) = delete;
int functor = 0; int functor = 0;
void* data = nullptr; void* data = nullptr;
AwDrawFnFunctorCallbacks* functor_callbacks = nullptr; AwDrawFnFunctorCallbacks* functor_callbacks = nullptr;
bool released_by_functor = false; bool released_by_functor = false;
bool released_by_manager = false; bool released_by_manager = false;
scoped_refptr<gfx::SurfaceControl::Surface> overlay_surface;
}; };
class Allocator { class Allocator {
...@@ -27,7 +40,7 @@ class Allocator { ...@@ -27,7 +40,7 @@ class Allocator {
static Allocator* Get(); static Allocator* Get();
int allocate(void* data, AwDrawFnFunctorCallbacks* functor_callbacks); int allocate(void* data, AwDrawFnFunctorCallbacks* functor_callbacks);
FunctorData get(int functor); FunctorData& get(int functor);
void MarkReleasedByFunctor(int functor); void MarkReleasedByFunctor(int functor);
void MarkReleasedByManager(int functor); void MarkReleasedByManager(int functor);
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "base/android/jni_array.h" #include "base/android/jni_array.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/native_library.h" #include "base/native_library.h"
#include "base/notreached.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
namespace draw_fn { namespace draw_fn {
...@@ -129,30 +128,28 @@ void ContextManager::SetSurface( ...@@ -129,30 +128,28 @@ void ContextManager::SetSurface(
} }
} }
void ContextManager::SetOverlaysSurface(
JNIEnv* env,
const base::android::JavaRef<jobject>& surface) {
overlays_manager_.SetSurface(current_functor_, env, surface);
}
void ContextManager::Sync(JNIEnv* env, int functor, bool apply_force_dark) { void ContextManager::Sync(JNIEnv* env, int functor, bool apply_force_dark) {
if (current_functor_ && current_functor_ != functor) { if (current_functor_ && current_functor_ != functor) {
FunctorData data = Allocator::Get()->get(current_functor_); FunctorData& data = Allocator::Get()->get(current_functor_);
overlays_manager_.RemoveOverlays(data);
data.functor_callbacks->on_context_destroyed(data.functor, data.data); data.functor_callbacks->on_context_destroyed(data.functor, data.data);
Allocator::Get()->MarkReleasedByManager(current_functor_); Allocator::Get()->MarkReleasedByManager(current_functor_);
} }
current_functor_ = functor; current_functor_ = functor;
FunctorData data = Allocator::Get()->get(current_functor_); FunctorData& data = Allocator::Get()->get(current_functor_);
AwDrawFn_OnSyncParams params{kAwDrawFnVersion, apply_force_dark}; AwDrawFn_OnSyncParams params{kAwDrawFnVersion, apply_force_dark};
data.functor_callbacks->on_sync(current_functor_, data.data, &params); data.functor_callbacks->on_sync(current_functor_, data.data, &params);
} }
namespace { namespace {
ASurfaceControl* GetSurfaceControl() {
NOTREACHED();
return nullptr;
}
void MergeTransaction(ASurfaceTransaction* transaction) {
NOTREACHED();
}
EGLDisplay GetDisplay() { EGLDisplay GetDisplay() {
static EGLDisplay display = eglGetDisplayFn(EGL_DEFAULT_DISPLAY); static EGLDisplay display = eglGetDisplayFn(EGL_DEFAULT_DISPLAY);
CHECK_NE(display, EGL_NO_DISPLAY); CHECK_NE(display, EGL_NO_DISPLAY);
...@@ -183,7 +180,6 @@ base::android::ScopedJavaLocalRef<jintArray> ContextManager::Draw( ...@@ -183,7 +180,6 @@ base::android::ScopedJavaLocalRef<jintArray> ContextManager::Draw(
MakeCurrent(); MakeCurrent();
FunctorData data = Allocator::Get()->get(current_functor_);
AwDrawFn_DrawGLParams params{kAwDrawFnVersion}; AwDrawFn_DrawGLParams params{kAwDrawFnVersion};
params.width = width; params.width = width;
params.height = height; params.height = height;
...@@ -229,10 +225,8 @@ base::android::ScopedJavaLocalRef<jintArray> ContextManager::Draw( ...@@ -229,10 +225,8 @@ base::android::ScopedJavaLocalRef<jintArray> ContextManager::Draw(
params.color_space_toXYZD50[7] = 0.0970921f; params.color_space_toXYZD50[7] = 0.0970921f;
params.color_space_toXYZD50[8] = 0.714191; params.color_space_toXYZD50[8] = 0.714191;
params.overlays_mode = AW_DRAW_FN_OVERLAYS_MODE_DISABLED; FunctorData& data = Allocator::Get()->get(current_functor_);
params.get_surface_control = GetSurfaceControl; OverlaysManager::ScopedDraw scoped_draw(overlays_manager_, data, params);
params.merge_transaction = MergeTransaction;
data.functor_callbacks->draw_gl(current_functor_, data.data, &params); data.functor_callbacks->draw_gl(current_functor_, data.data, &params);
if (readback_quadrants) { if (readback_quadrants) {
...@@ -351,7 +345,8 @@ void ContextManager::DestroyContext() { ...@@ -351,7 +345,8 @@ void ContextManager::DestroyContext() {
if (current_functor_) { if (current_functor_) {
MakeCurrent(); MakeCurrent();
FunctorData data = Allocator::Get()->get(current_functor_); FunctorData& data = Allocator::Get()->get(current_functor_);
overlays_manager_.RemoveOverlays(data);
data.functor_callbacks->on_context_destroyed(data.functor, data.data); data.functor_callbacks->on_context_destroyed(data.functor, data.data);
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <android/native_window.h> #include <android/native_window.h>
#include <jni.h> #include <jni.h>
#include "android_webview/test/shell/src/draw_fn/overlays_manager.h"
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
typedef void* EGLContext; typedef void* EGLContext;
...@@ -21,6 +22,8 @@ class ContextManager { ...@@ -21,6 +22,8 @@ class ContextManager {
~ContextManager(); ~ContextManager();
void SetSurface(JNIEnv* env, const base::android::JavaRef<jobject>& surface); void SetSurface(JNIEnv* env, const base::android::JavaRef<jobject>& surface);
void SetOverlaysSurface(JNIEnv* env,
const base::android::JavaRef<jobject>& surface);
void Sync(JNIEnv* env, int functor, bool apply_force_dark); void Sync(JNIEnv* env, int functor, bool apply_force_dark);
base::android::ScopedJavaLocalRef<jintArray> Draw( base::android::ScopedJavaLocalRef<jintArray> Draw(
JNIEnv* env, JNIEnv* env,
...@@ -42,6 +45,8 @@ class ContextManager { ...@@ -42,6 +45,8 @@ class ContextManager {
EGLContext context_ = nullptr; EGLContext context_ = nullptr;
int current_functor_ = 0; int current_functor_ = 0;
OverlaysManager overlays_manager_;
}; };
} // namespace draw_fn } // namespace draw_fn
......
// Copyright 2020 The Chromium 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 "android_webview/test/shell/src/draw_fn/overlays_manager.h"
#include <android/native_window_jni.h>
#include "android_webview/public/browser/draw_fn.h"
#include "android_webview/test/shell/src/draw_fn/allocator.h"
#include "base/android/jni_array.h"
#include "base/logging.h"
namespace draw_fn {
namespace {
bool AreOverlaysSupported() {
static bool supported = gfx::SurfaceControl::IsSupported();
return supported;
}
OverlaysManager::ScopedCurrentFunctorCall* g_current_functor_call = nullptr;
} // namespace
class OverlaysManager::ScopedCurrentFunctorCall {
public:
ScopedCurrentFunctorCall(FunctorData& functor, ANativeWindow* native_window)
: functor_(functor), native_window_(native_window) {
DCHECK(!g_current_functor_call);
g_current_functor_call = this;
}
~ScopedCurrentFunctorCall() {
DCHECK_EQ(g_current_functor_call, this);
g_current_functor_call = nullptr;
}
static ASurfaceControl* GetSurfaceControlFn() {
DCHECK(g_current_functor_call);
DCHECK(AreOverlaysSupported());
return g_current_functor_call->GetSurfaceControl();
}
static void MergeTransactionFn(ASurfaceTransaction* transaction) {
DCHECK(g_current_functor_call);
DCHECK(AreOverlaysSupported());
return g_current_functor_call->MergeTransaction(transaction);
}
private:
ASurfaceControl* GetSurfaceControl() {
if (!functor_.overlay_surface) {
DCHECK(native_window_);
functor_.overlay_surface =
base::MakeRefCounted<gfx::SurfaceControl::Surface>(native_window_,
"webview_root");
}
return functor_.overlay_surface->surface();
}
void MergeTransaction(ASurfaceTransaction* transaction) {
gfx::SurfaceControl::ApplyTransaction(transaction);
}
FunctorData& functor_;
ANativeWindow* native_window_;
};
OverlaysManager::ScopedDraw::ScopedDraw(OverlaysManager& manager,
FunctorData& functor,
AwDrawFn_DrawGLParams& params)
: scoped_functor_call_(
std::make_unique<ScopedCurrentFunctorCall>(functor,
manager.native_window_)) {
params.overlays_mode = (AreOverlaysSupported() && manager.native_window_)
? AW_DRAW_FN_OVERLAYS_MODE_ENABLED
: AW_DRAW_FN_OVERLAYS_MODE_DISABLED;
params.get_surface_control = ScopedCurrentFunctorCall::GetSurfaceControlFn;
params.merge_transaction = ScopedCurrentFunctorCall::MergeTransactionFn;
}
OverlaysManager::ScopedDraw::~ScopedDraw() = default;
OverlaysManager::OverlaysManager() = default;
OverlaysManager::~OverlaysManager() = default;
void OverlaysManager::RemoveOverlays(FunctorData& functor) {
if (functor.overlay_surface) {
ScopedCurrentFunctorCall current_call(functor, nullptr);
AwDrawFn_RemoveOverlaysParams params = {
.version = kAwDrawFnVersion,
.merge_transaction = ScopedCurrentFunctorCall::MergeTransactionFn};
functor.functor_callbacks->remove_overlays(functor.functor, functor.data,
&params);
functor.overlay_surface.reset();
}
}
void OverlaysManager::SetSurface(
int current_functor,
JNIEnv* env,
const base::android::JavaRef<jobject>& surface) {
if (java_surface_.obj() == surface.obj())
return;
if (native_window_) {
if (current_functor)
RemoveOverlays(Allocator::Get()->get(current_functor));
ANativeWindow_release(native_window_);
native_window_ = nullptr;
}
java_surface_.Reset(surface);
if (java_surface_) {
native_window_ = ANativeWindow_fromSurface(env, java_surface_.obj());
}
}
} // namespace draw_fn
// Copyright 2020 The Chromium 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 ANDROID_WEBVIEW_TEST_SHELL_SRC_DRAW_FN_OVERLAYS_MANAGER_H_
#define ANDROID_WEBVIEW_TEST_SHELL_SRC_DRAW_FN_OVERLAYS_MANAGER_H_
#include <android/native_window.h>
#include <jni.h>
#include "base/android/scoped_java_ref.h"
#include "ui/gfx/android/android_surface_control_compat.h"
struct AwDrawFn_DrawGLParams;
namespace draw_fn {
struct FunctorData;
class OverlaysManager {
public:
class ScopedCurrentFunctorCall;
class ScopedDraw {
public:
ScopedDraw(OverlaysManager& manager,
FunctorData& functor,
AwDrawFn_DrawGLParams& params);
~ScopedDraw();
private:
std::unique_ptr<ScopedCurrentFunctorCall> scoped_functor_call_;
};
OverlaysManager();
~OverlaysManager();
void RemoveOverlays(FunctorData& functor);
void SetSurface(int current_functor,
JNIEnv* env,
const base::android::JavaRef<jobject>& surface);
private:
base::android::ScopedJavaGlobalRef<jobject> java_surface_;
ANativeWindow* native_window_ = nullptr;
};
} // namespace draw_fn
#endif // ANDROID_WEBVIEW_TEST_SHELL_SRC_DRAW_FN_OVERLAYS_MANAGER_H_
...@@ -29,6 +29,10 @@ public class ContextManager { ...@@ -29,6 +29,10 @@ public class ContextManager {
nativeSetSurface(mNativeContextManager, surface); nativeSetSurface(mNativeContextManager, surface);
} }
public void setOverlaysSurface(Surface surface) {
nativeSetOverlaysSurface(mNativeContextManager, surface);
}
public void sync(int functor, boolean applyForceDark) { public void sync(int functor, boolean applyForceDark) {
nativeSync(mNativeContextManager, functor, applyForceDark); nativeSync(mNativeContextManager, functor, applyForceDark);
} }
...@@ -42,6 +46,7 @@ public class ContextManager { ...@@ -42,6 +46,7 @@ public class ContextManager {
private static native long nativeGetDrawFnFunctionTable(); private static native long nativeGetDrawFnFunctionTable();
private static native long nativeInit(); private static native long nativeInit();
private static native void nativeSetSurface(long nativeContextManager, Surface surface); private static native void nativeSetSurface(long nativeContextManager, Surface surface);
private static native void nativeSetOverlaysSurface(long nativeContextManager, Surface surface);
private static native void nativeSync( private static native void nativeSync(
long nativeContextManager, int functor, boolean applyForceDark); long nativeContextManager, int functor, boolean applyForceDark);
private static native int[] nativeDraw(long nativeContextManager, int width, int height, private static native int[] nativeDraw(long nativeContextManager, int width, int height,
......
...@@ -83,6 +83,7 @@ public class AwTestContainerView extends FrameLayout { ...@@ -83,6 +83,7 @@ public class AwTestContainerView extends FrameLayout {
private int mLastScrollY; private int mLastScrollY;
private boolean mHaveSurface; private boolean mHaveSurface;
private Runnable mReadyToRenderCallback; private Runnable mReadyToRenderCallback;
private SurfaceView mOverlaysSurfaceView;
// Only accessed on render thread. // Only accessed on render thread.
private final ContextManager mContextManager; private final ContextManager mContextManager;
...@@ -95,8 +96,17 @@ public class AwTestContainerView extends FrameLayout { ...@@ -95,8 +96,17 @@ public class AwTestContainerView extends FrameLayout {
sRenderThreadHandler = new Handler(sRenderThread.getLooper()); sRenderThreadHandler = new Handler(sRenderThread.getLooper());
} }
mContextManager = new ContextManager(); mContextManager = new ContextManager();
getHolder().setFormat(PixelFormat.OPAQUE); getHolder().setFormat(PixelFormat.TRANSPARENT);
getHolder().addCallback(this); getHolder().addCallback(this);
// Main SurfaceView needs to be positioned above the media content.
setZOrderMediaOverlay(true);
mOverlaysSurfaceView = new SurfaceView(context);
mOverlaysSurfaceView.getHolder().addCallback(this);
// This SurfaceView is used to present media and must be positioned below main surface.
mOverlaysSurfaceView.setZOrderMediaOverlay(false);
} }
public void readbackQuadrantColors(Callback<int[]> callback) { public void readbackQuadrantColors(Callback<int[]> callback) {
...@@ -115,11 +125,21 @@ public class AwTestContainerView extends FrameLayout { ...@@ -115,11 +125,21 @@ public class AwTestContainerView extends FrameLayout {
mReadyToRenderCallback = runner; mReadyToRenderCallback = runner;
} }
public SurfaceView getOverlaysView() {
return mOverlaysSurfaceView;
}
@Override @Override
public void surfaceCreated(SurfaceHolder holder) {} public void surfaceCreated(SurfaceHolder holder) {}
@Override @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder == mOverlaysSurfaceView.getHolder()) {
Surface surface = holder.getSurface();
sRenderThreadHandler.post(() -> { mContextManager.setOverlaysSurface(surface); });
return;
}
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
mHaveSurface = true; mHaveSurface = true;
...@@ -135,6 +155,16 @@ public class AwTestContainerView extends FrameLayout { ...@@ -135,6 +155,16 @@ public class AwTestContainerView extends FrameLayout {
@Override @Override
public void surfaceDestroyed(SurfaceHolder holder) { public void surfaceDestroyed(SurfaceHolder holder) {
if (holder == mOverlaysSurfaceView.getHolder()) {
WaitableEvent event = new WaitableEvent();
sRenderThreadHandler.post(() -> {
mContextManager.setOverlaysSurface(null);
event.signal();
});
event.waitForEvent();
return;
}
mHaveSurface = false; mHaveSurface = false;
WaitableEvent event = new WaitableEvent(); WaitableEvent event = new WaitableEvent();
sRenderThreadHandler.post(() -> { sRenderThreadHandler.post(() -> {
...@@ -182,6 +212,9 @@ public class AwTestContainerView extends FrameLayout { ...@@ -182,6 +212,9 @@ public class AwTestContainerView extends FrameLayout {
mHardwareView = createHardwareViewOnlyOnce(context); mHardwareView = createHardwareViewOnlyOnce(context);
} }
if (isBackedByHardwareView()) { if (isBackedByHardwareView()) {
addView(mHardwareView.getOverlaysView(),
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
addView(mHardwareView, addView(mHardwareView,
new FrameLayout.LayoutParams( new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT,
......
...@@ -351,6 +351,10 @@ bool SurfaceControl::SupportsSetFrameRate() { ...@@ -351,6 +351,10 @@ bool SurfaceControl::SupportsSetFrameRate() {
nullptr; nullptr;
} }
void SurfaceControl::ApplyTransaction(ASurfaceTransaction* transaction) {
SurfaceControlMethods::Get().ASurfaceTransaction_applyFn(transaction);
}
SurfaceControl::Surface::Surface() = default; SurfaceControl::Surface::Surface() = default;
SurfaceControl::Surface::Surface(const Surface& parent, const char* name) { SurfaceControl::Surface::Surface(const Surface& parent, const char* name) {
......
...@@ -47,6 +47,11 @@ class GFX_EXPORT SurfaceControl { ...@@ -47,6 +47,11 @@ class GFX_EXPORT SurfaceControl {
// Returns true if tagging a surface with a frame rate value is supported. // Returns true if tagging a surface with a frame rate value is supported.
static bool SupportsSetFrameRate(); static bool SupportsSetFrameRate();
// Applies transaction. Used to emulate webview functor interface, where we
// pass raw ASurfaceTransaction object. For use inside Chromium use
// Transaction class below instead.
static void ApplyTransaction(ASurfaceTransaction* transaction);
class GFX_EXPORT Surface : public base::RefCounted<Surface> { class GFX_EXPORT Surface : public base::RefCounted<Surface> {
public: public:
Surface(); Surface();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment