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") {
"shell/src/draw_fn/allocator.h",
"shell/src/draw_fn/context_manager.cc",
"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" ]
deps = [
......
......@@ -41,6 +41,16 @@ AwDrawFnFunctionTable* GetDrawFnFunctionTable() {
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
Allocator* Allocator::Get() {
static base::NoDestructor<Allocator> map;
......@@ -54,11 +64,11 @@ int Allocator::allocate(void* data,
AwDrawFnFunctorCallbacks* functor_callbacks) {
base::AutoLock lock(lock_);
int functor = next_functor_++;
map_.emplace(functor, FunctorData{functor, data, functor_callbacks});
map_.emplace(functor, FunctorData(functor, data, functor_callbacks));
return functor;
}
FunctorData Allocator::get(int functor) {
FunctorData& Allocator::get(int functor) {
base::AutoLock lock(lock_);
auto itr = map_.find(functor);
DCHECK(itr != map_.end());
......
......@@ -9,17 +9,30 @@
#include "base/containers/flat_map.h"
#include "base/no_destructor.h"
#include "base/synchronization/lock.h"
#include "ui/gfx/android/android_surface_control_compat.h"
namespace draw_fn {
AwDrawFnFunctionTable* GetDrawFnFunctionTable();
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;
void* data = nullptr;
AwDrawFnFunctorCallbacks* functor_callbacks = nullptr;
bool released_by_functor = false;
bool released_by_manager = false;
scoped_refptr<gfx::SurfaceControl::Surface> overlay_surface;
};
class Allocator {
......@@ -27,7 +40,7 @@ class Allocator {
static Allocator* Get();
int allocate(void* data, AwDrawFnFunctorCallbacks* functor_callbacks);
FunctorData get(int functor);
FunctorData& get(int functor);
void MarkReleasedByFunctor(int functor);
void MarkReleasedByManager(int functor);
......
......@@ -14,7 +14,6 @@
#include "base/android/jni_array.h"
#include "base/logging.h"
#include "base/native_library.h"
#include "base/notreached.h"
#include "base/threading/thread_restrictions.h"
namespace draw_fn {
......@@ -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) {
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);
Allocator::Get()->MarkReleasedByManager(current_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};
data.functor_callbacks->on_sync(current_functor_, data.data, &params);
}
namespace {
ASurfaceControl* GetSurfaceControl() {
NOTREACHED();
return nullptr;
}
void MergeTransaction(ASurfaceTransaction* transaction) {
NOTREACHED();
}
EGLDisplay GetDisplay() {
static EGLDisplay display = eglGetDisplayFn(EGL_DEFAULT_DISPLAY);
CHECK_NE(display, EGL_NO_DISPLAY);
......@@ -183,7 +180,6 @@ base::android::ScopedJavaLocalRef<jintArray> ContextManager::Draw(
MakeCurrent();
FunctorData data = Allocator::Get()->get(current_functor_);
AwDrawFn_DrawGLParams params{kAwDrawFnVersion};
params.width = width;
params.height = height;
......@@ -229,10 +225,8 @@ base::android::ScopedJavaLocalRef<jintArray> ContextManager::Draw(
params.color_space_toXYZD50[7] = 0.0970921f;
params.color_space_toXYZD50[8] = 0.714191;
params.overlays_mode = AW_DRAW_FN_OVERLAYS_MODE_DISABLED;
params.get_surface_control = GetSurfaceControl;
params.merge_transaction = MergeTransaction;
FunctorData& data = Allocator::Get()->get(current_functor_);
OverlaysManager::ScopedDraw scoped_draw(overlays_manager_, data, params);
data.functor_callbacks->draw_gl(current_functor_, data.data, &params);
if (readback_quadrants) {
......@@ -351,7 +345,8 @@ void ContextManager::DestroyContext() {
if (current_functor_) {
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);
}
......
......@@ -8,6 +8,7 @@
#include <android/native_window.h>
#include <jni.h>
#include "android_webview/test/shell/src/draw_fn/overlays_manager.h"
#include "base/android/scoped_java_ref.h"
typedef void* EGLContext;
......@@ -21,6 +22,8 @@ class ContextManager {
~ContextManager();
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);
base::android::ScopedJavaLocalRef<jintArray> Draw(
JNIEnv* env,
......@@ -42,6 +45,8 @@ class ContextManager {
EGLContext context_ = nullptr;
int current_functor_ = 0;
OverlaysManager overlays_manager_;
};
} // 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 {
nativeSetSurface(mNativeContextManager, surface);
}
public void setOverlaysSurface(Surface surface) {
nativeSetOverlaysSurface(mNativeContextManager, surface);
}
public void sync(int functor, boolean applyForceDark) {
nativeSync(mNativeContextManager, functor, applyForceDark);
}
......@@ -42,6 +46,7 @@ public class ContextManager {
private static native long nativeGetDrawFnFunctionTable();
private static native long nativeInit();
private static native void nativeSetSurface(long nativeContextManager, Surface surface);
private static native void nativeSetOverlaysSurface(long nativeContextManager, Surface surface);
private static native void nativeSync(
long nativeContextManager, int functor, boolean applyForceDark);
private static native int[] nativeDraw(long nativeContextManager, int width, int height,
......
......@@ -83,6 +83,7 @@ public class AwTestContainerView extends FrameLayout {
private int mLastScrollY;
private boolean mHaveSurface;
private Runnable mReadyToRenderCallback;
private SurfaceView mOverlaysSurfaceView;
// Only accessed on render thread.
private final ContextManager mContextManager;
......@@ -95,8 +96,17 @@ public class AwTestContainerView extends FrameLayout {
sRenderThreadHandler = new Handler(sRenderThread.getLooper());
}
mContextManager = new ContextManager();
getHolder().setFormat(PixelFormat.OPAQUE);
getHolder().setFormat(PixelFormat.TRANSPARENT);
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) {
......@@ -115,11 +125,21 @@ public class AwTestContainerView extends FrameLayout {
mReadyToRenderCallback = runner;
}
public SurfaceView getOverlaysView() {
return mOverlaysSurfaceView;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {}
@Override
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;
mHeight = height;
mHaveSurface = true;
......@@ -135,6 +155,16 @@ public class AwTestContainerView extends FrameLayout {
@Override
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;
WaitableEvent event = new WaitableEvent();
sRenderThreadHandler.post(() -> {
......@@ -182,6 +212,9 @@ public class AwTestContainerView extends FrameLayout {
mHardwareView = createHardwareViewOnlyOnce(context);
}
if (isBackedByHardwareView()) {
addView(mHardwareView.getOverlaysView(),
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
addView(mHardwareView,
new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
......
......@@ -351,6 +351,10 @@ bool SurfaceControl::SupportsSetFrameRate() {
nullptr;
}
void SurfaceControl::ApplyTransaction(ASurfaceTransaction* transaction) {
SurfaceControlMethods::Get().ASurfaceTransaction_applyFn(transaction);
}
SurfaceControl::Surface::Surface() = default;
SurfaceControl::Surface::Surface(const Surface& parent, const char* name) {
......
......@@ -47,6 +47,11 @@ class GFX_EXPORT SurfaceControl {
// Returns true if tagging a surface with a frame rate value is supported.
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> {
public:
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