Commit 5c21ea63 authored by Khushal's avatar Khushal Committed by Commit Bot

gl/android: Update SurfaceControl impl based on NDK updates.

Update the SurfaceControl ABI based on NDK changes and hook up
transaction acks from the framework for GLSurface swap acks.

Change-Id: I7919bbe97cc621c1912657ed4c1894ede8308fab
Bug: 889328
Reviewed-on: https://chromium-review.googlesource.com/c/1347792Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Commit-Queue: Khushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611870}
parent 87bfbed5
......@@ -29,6 +29,11 @@ class OverlayCandidateValidatorImpl : public OverlayCandidateValidator {
// Only update the last candidate that was added to the list. All previous
// overlays should have already been handled.
auto& candidate = surfaces->back();
if (candidate.transform != gfx::OVERLAY_TRANSFORM_NONE) {
candidate.overlay_handled = false;
return;
}
candidate.display_rect =
gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect));
candidate.overlay_handled = true;
......
......@@ -31,7 +31,7 @@
#if defined(OS_ANDROID)
#include "base/no_destructor.h"
#include "base/synchronization/lock.h"
#include "ui/gl/android/android_surface_composer_compat.h"
#include "ui/gl/android/android_surface_control_compat.h"
#include "ui/gl/init/gl_factory.h"
#endif // OS_ANDROID
......@@ -51,7 +51,7 @@ GpuFeatureStatus GetAndroidSurfaceControlFeatureStatus(
if (!gpu_preferences.enable_android_surface_control)
return kGpuFeatureStatusDisabled;
if (!gl::SurfaceComposer::IsSupported())
if (!gl::SurfaceControl::IsSupported())
return kGpuFeatureStatusDisabled;
return kGpuFeatureStatusEnabled;
......
......@@ -6,6 +6,7 @@
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/ipc/common/gpu_surface_lookup.h"
......@@ -38,7 +39,8 @@ scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface(
if (delegate &&
delegate->GetFeatureInfo()->feature_flags().android_surface_control) {
surface = new gl::GLSurfaceEGLSurfaceControl(window);
surface = new gl::GLSurfaceEGLSurfaceControl(
window, base::ThreadTaskRunnerHandle::Get());
} else {
surface = new gl::NativeViewGLSurfaceEGL(window, nullptr);
}
......
......@@ -53,8 +53,8 @@ jumbo_component("gl") {
output_name = "gl_wrapper" # Avoid colliding with OS X"s libGL.dylib.
sources = [
"android/android_surface_composer_compat.cc",
"android/android_surface_composer_compat.h",
"android/android_surface_control_compat.cc",
"android/android_surface_control_compat.h",
"android/scoped_java_surface.cc",
"android/scoped_java_surface.h",
"android/surface_texture.cc",
......
This diff is collapsed.
// Copyright 2018 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 "ui/gl/android/android_surface_control_compat.h"
#include <dlfcn.h>
#include "base/android/build_info.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
extern "C" {
// ASurface
using pASurfaceControl_CreateSurfaceForWindow =
ASurface* (*)(ANativeWindow* parent, const char* name);
using pASurfaceControl_CreateSurface = ASurface* (*)(ASurface* parent,
const char* name);
using pASurfaceControl_DeleteSurface = void (*)(ASurface*);
// ASurfaceTransaction
using pASurfaceControl_CreateTransaction = ASurfaceTransaction* (*)(void);
using pASurfaceControl_DeleteTransaction = void (*)(ASurfaceTransaction*);
using pASurfaceControl_TransactionApply = int64_t (*)(ASurfaceTransaction*);
using pASurfaceControl_TransactionSetCompletedFunc =
void (*)(ASurfaceTransaction*, void* ctx, TransactionCompletedFunc);
using pASurfaceControl_TransactionSetVisibility = void (*)(ASurfaceTransaction*,
ASurface*,
bool show);
using pASurfaceControl_TransactionSetZOrder =
void (*)(ASurfaceTransaction* transaction, ASurface*, int32_t z);
using pASurfaceControl_TransactionSetBuffer =
void (*)(ASurfaceTransaction* transaction,
ASurface*,
AHardwareBuffer*,
int32_t fence_fd);
using pASurfaceControl_TransactionSetCropRect =
void (*)(ASurfaceTransaction* transaction,
ASurface* surface,
const ARect& rect);
using pASurfaceControl_TransactionSetDisplayFrame =
void (*)(ASurfaceTransaction* transaction,
ASurface* surface,
const ARect& rect);
using pASurfaceControl_TransactionSetBufferOpaque =
void (*)(ASurfaceTransaction* transaction, ASurface* surface, bool opaque);
using pASurfaceControl_TransactionSetDamageRegion =
void (*)(ASurfaceTransaction* transaction,
ASurface* surface,
const ARect rects[],
uint32_t count);
}
namespace gl {
namespace {
#define LOAD_FUNCTION(lib, func) \
do { \
func##Fn = reinterpret_cast<p##func>(dlsym(lib, #func)); \
if (!func##Fn) { \
supported = false; \
LOG(ERROR) << "Unable to load function " << #func; \
} \
} while (0)
struct SurfaceControlMethods {
public:
static const SurfaceControlMethods& Get() {
static const base::NoDestructor<SurfaceControlMethods> instance;
return *instance;
}
SurfaceControlMethods() {
void* main_dl_handle = dlopen(nullptr, RTLD_NOW);
if (!main_dl_handle) {
LOG(ERROR) << "Couldnt load android so";
supported = false;
return;
}
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_CreateSurfaceForWindow);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_CreateSurface);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_DeleteSurface);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_CreateTransaction);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_DeleteTransaction);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionApply);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetCompletedFunc);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetVisibility);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetZOrder);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetBuffer);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetCropRect);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetDisplayFrame);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetBufferOpaque);
LOAD_FUNCTION(main_dl_handle, ASurfaceControl_TransactionSetDamageRegion);
}
~SurfaceControlMethods() = default;
bool supported = true;
// Surface methods.
pASurfaceControl_CreateSurfaceForWindow
ASurfaceControl_CreateSurfaceForWindowFn;
pASurfaceControl_CreateSurface ASurfaceControl_CreateSurfaceFn;
pASurfaceControl_DeleteSurface ASurfaceControl_DeleteSurfaceFn;
// Transaction methods.
pASurfaceControl_CreateTransaction ASurfaceControl_CreateTransactionFn;
pASurfaceControl_DeleteTransaction ASurfaceControl_DeleteTransactionFn;
pASurfaceControl_TransactionApply ASurfaceControl_TransactionApplyFn;
pASurfaceControl_TransactionSetCompletedFunc
ASurfaceControl_TransactionSetCompletedFuncFn;
pASurfaceControl_TransactionSetVisibility
ASurfaceControl_TransactionSetVisibilityFn;
pASurfaceControl_TransactionSetZOrder ASurfaceControl_TransactionSetZOrderFn;
pASurfaceControl_TransactionSetBuffer ASurfaceControl_TransactionSetBufferFn;
pASurfaceControl_TransactionSetCropRect
ASurfaceControl_TransactionSetCropRectFn;
pASurfaceControl_TransactionSetDisplayFrame
ASurfaceControl_TransactionSetDisplayFrameFn;
pASurfaceControl_TransactionSetBufferOpaque
ASurfaceControl_TransactionSetBufferOpaqueFn;
pASurfaceControl_TransactionSetDamageRegion
ASurfaceControl_TransactionSetDamageRegionFn;
};
ARect RectToARect(const gfx::Rect& rect) {
return ARect{rect.x(), rect.y(), rect.right(), rect.bottom()};
}
};
// static
bool SurfaceControl::IsSupported() {
#if 0
// TODO(khushalsagar): Enable this code when the frame is correctly reporting
// SDK version for P+.
const int sdk_int = base::android::BuildInfo::GetInstance()->sdk_int();
if (sdk_int < 29) {
LOG(ERROR) << "SurfaceControl not supported on sdk: " << sdk_int;
return false;
}
#endif
return SurfaceControlMethods::Get().supported;
}
SurfaceControl::Surface::Surface() = default;
SurfaceControl::Surface::Surface(const Surface& parent, const char* name) {
surface_ = SurfaceControlMethods::Get().ASurfaceControl_CreateSurfaceFn(
parent.surface(), name);
DCHECK(surface_);
}
SurfaceControl::Surface::Surface(ANativeWindow* parent, const char* name) {
surface_ =
SurfaceControlMethods::Get().ASurfaceControl_CreateSurfaceForWindowFn(
parent, name);
DCHECK(surface_);
}
SurfaceControl::Surface::~Surface() {
if (surface_)
SurfaceControlMethods::Get().ASurfaceControl_DeleteSurfaceFn(surface_);
}
SurfaceControl::Surface::Surface(Surface&& other) {
surface_ = other.surface_;
other.surface_ = nullptr;
}
SurfaceControl::Surface& SurfaceControl::Surface::operator=(Surface&& other) {
if (surface_)
SurfaceControlMethods::Get().ASurfaceControl_DeleteSurfaceFn(surface_);
surface_ = other.surface_;
other.surface_ = nullptr;
return *this;
}
SurfaceControl::Transaction::Transaction() {
transaction_ =
SurfaceControlMethods::Get().ASurfaceControl_CreateTransactionFn();
DCHECK(transaction_);
}
SurfaceControl::Transaction::~Transaction() {
SurfaceControlMethods::Get().ASurfaceControl_DeleteTransactionFn(
transaction_);
}
void SurfaceControl::Transaction::SetVisibility(const Surface& surface,
bool show) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetVisibilityFn(
transaction_, surface.surface(), show);
}
void SurfaceControl::Transaction::SetZOrder(const Surface& surface, int32_t z) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetZOrderFn(
transaction_, surface.surface(), z);
}
void SurfaceControl::Transaction::SetBuffer(const Surface& surface,
AHardwareBuffer* buffer,
base::ScopedFD fence_fd) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetBufferFn(
transaction_, surface.surface(), buffer,
fence_fd.is_valid() ? fence_fd.release() : -1);
}
void SurfaceControl::Transaction::SetCropRect(const Surface& surface,
const gfx::Rect& rect) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetCropRectFn(
transaction_, surface.surface(), RectToARect(rect));
}
void SurfaceControl::Transaction::SetDisplayFrame(const Surface& surface,
const gfx::Rect& rect) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetDisplayFrameFn(
transaction_, surface.surface(), RectToARect(rect));
}
void SurfaceControl::Transaction::SetOpaque(const Surface& surface,
bool opaque) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetBufferOpaqueFn(
transaction_, surface.surface(), opaque);
}
void SurfaceControl::Transaction::SetDamageRect(const Surface& surface,
const gfx::Rect& rect) {
auto a_rect = RectToARect(rect);
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetDamageRegionFn(
transaction_, surface.surface(), &a_rect, 1u);
}
void SurfaceControl::Transaction::SetCompletedFunc(
TransactionCompletedFunc func,
void* ctx) {
SurfaceControlMethods::Get().ASurfaceControl_TransactionSetCompletedFuncFn(
transaction_, ctx, func);
}
void SurfaceControl::Transaction::Apply() {
SurfaceControlMethods::Get().ASurfaceControl_TransactionApplyFn(transaction_);
}
} // namespace gl
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GL_ANDROID_ANDROID_SURFACE_COMPOSER_COMPAT_H_
#define UI_GL_ANDROID_ANDROID_SURFACE_COMPOSER_COMPAT_H_
#ifndef UI_GL_ANDROID_ANDROID_SURFACE_CONTROL_COMPAT_H_
#define UI_GL_ANDROID_ANDROID_SURFACE_CONTROL_COMPAT_H_
#include <memory>
......@@ -11,30 +11,27 @@
#include <android/native_window.h>
#include "base/files/scoped_file.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gl/gl_export.h"
extern "C" {
typedef struct ASurface ASurface;
typedef struct ASurfaceComposer ASurfaceComposer;
typedef struct ASurfaceTransaction ASurfaceTransaction;
typedef void (*TransactionCompletedFunc)(void* context,
int64_t present_time_ns);
}
namespace gl {
class GL_EXPORT SurfaceComposer {
class GL_EXPORT SurfaceControl {
public:
enum class SurfaceContentType : int32_t {
kNone = 0,
kAHardwareBuffer = 1,
};
static bool IsSupported();
class GL_EXPORT Surface {
public:
Surface();
Surface(SurfaceComposer* composer,
SurfaceContentType content_type,
const char* name,
Surface* parent = nullptr);
Surface(const Surface& parent, const char* name);
Surface(ANativeWindow* parent, const char* name);
~Surface();
Surface(Surface&& other);
......@@ -52,35 +49,21 @@ class GL_EXPORT SurfaceComposer {
~Transaction();
void SetVisibility(const Surface& surface, bool show);
void SetPosition(const Surface& surface, float x, float y);
void SetZOrder(const Surface& surface, int32_t z);
void SetBuffer(const Surface& surface,
AHardwareBuffer* buffer,
base::ScopedFD fence_fd);
void SetSize(const Surface& surface, uint32_t width, uint32_t height);
void SetCropRect(const Surface& surface,
int32_t left,
int32_t top,
int32_t right,
int32_t bottom);
void SetCropRect(const Surface& surface, const gfx::Rect& rect);
void SetDisplayFrame(const Surface& surface, const gfx::Rect& rect);
void SetOpaque(const Surface& surface, bool opaque);
void SetDamageRect(const Surface& surface, const gfx::Rect& rect);
void SetCompletedFunc(TransactionCompletedFunc func, void* ctx);
void Apply();
private:
ASurfaceTransaction* transaction_;
};
static bool IsSupported();
static std::unique_ptr<SurfaceComposer> Create(ANativeWindow* window);
~SurfaceComposer();
private:
explicit SurfaceComposer(ASurfaceComposer* composer);
ASurfaceComposer* composer_;
};
}; // namespace gl
#endif // UI_GL_ANDROID_ANDROID_SURFACE_COMPOSER_COMPAT_H_
#endif // UI_GL_ANDROID_ANDROID_SURFACE_CONTROL_COMPAT_H_
......@@ -4,6 +4,7 @@
#include "ui/gl/gl_surface_egl_surface_control.h"
#include "base/android/android_hardware_buffer_compat.h"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gl/gl_fence_android_native_fence_sync.h"
......@@ -12,16 +13,46 @@
namespace gl {
namespace {
constexpr char kSurfaceName[] = "ChromeSurface";
constexpr char kRootSurfaceName[] = "ChromeNativeWindowSurface";
constexpr char kChildSurfaceName[] = "ChromeChildSurface";
} // namespace
gfx::Size GetBufferSize(const AHardwareBuffer* buffer) {
AHardwareBuffer_Desc desc;
base::AndroidHardwareBufferCompat::GetInstance().Describe(buffer, &desc);
return gfx::Size(desc.width, desc.height);
}
GLSurfaceEGLSurfaceControl::GLSurfaceEGLSurfaceControl(ANativeWindow* window) {
surface_composer_ = SurfaceComposer::Create(window);
struct TransactionAckCtx {
scoped_refptr<base::SingleThreadTaskRunner> task_runner;
base::OnceCallback<void(int64_t)> callback;
};
// Note that the framework API states that this callback can be dispatched on
// any thread (in practice it should be the binder thread), so we need to post
// a task back to the GPU thread.
void OnTransactionCompletedOnAnyThread(void* ctx, int64_t present_time_ns) {
auto* ack_ctx = static_cast<TransactionAckCtx*>(ctx);
ack_ctx->task_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(ack_ctx->callback), present_time_ns));
delete ack_ctx;
}
} // namespace
GLSurfaceEGLSurfaceControl::GLSurfaceEGLSurfaceControl(
ANativeWindow* window,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: root_surface_(window, kRootSurfaceName),
gpu_task_runner_(std::move(task_runner)),
weak_factory_(this) {}
GLSurfaceEGLSurfaceControl::~GLSurfaceEGLSurfaceControl() = default;
int GLSurfaceEGLSurfaceControl::GetBufferCount() const {
// Triple buffering to match framework's BufferQueue.
return 3;
}
bool GLSurfaceEGLSurfaceControl::Initialize(GLSurfaceFormat format) {
format_ = format;
return true;
......@@ -30,7 +61,7 @@ bool GLSurfaceEGLSurfaceControl::Initialize(GLSurfaceFormat format) {
void GLSurfaceEGLSurfaceControl::Destroy() {
pending_transaction_.reset();
surface_list_.clear();
surface_composer_.reset();
root_surface_ = SurfaceControl::Surface();
}
bool GLSurfaceEGLSurfaceControl::Resize(const gfx::Size& size,
......@@ -83,25 +114,25 @@ void GLSurfaceEGLSurfaceControl::CommitPendingTransaction(
current_frame_resources_.swap(pending_frame_resources_);
pending_frame_resources_.clear();
// Set up the callback to be notified when the frame is presented by the
// framework. Note that it is assumed that all GPU/display work for this frame
// is finished when the callback is dispatched, and all resources from the
// previous frame can be reused.
TransactionAckCtx* ack_ctx = new TransactionAckCtx;
ack_ctx->task_runner = gpu_task_runner_;
ack_ctx->callback =
base::BindOnce(&GLSurfaceEGLSurfaceControl::OnTransactionAckOnGpuThread,
weak_factory_.GetWeakPtr(), completion_callback,
present_callback, std::move(resources_to_release));
pending_transaction_->SetCompletedFunc(&OnTransactionCompletedOnAnyThread,
ack_ctx);
pending_transaction_->Apply();
pending_transaction_.reset();
DCHECK_GE(surface_list_.size(), pending_surfaces_count_);
surface_list_.resize(pending_surfaces_count_);
pending_surfaces_count_ = 0u;
// TODO(khushalsagar): Send the legit timestamp when hooking up transaction
// acks.
constexpr int64_t kRefreshIntervalInMicroseconds =
base::Time::kMicrosecondsPerSecond / 60;
gfx::PresentationFeedback feedback(
base::TimeTicks::Now(),
base::TimeDelta::FromMicroseconds(kRefreshIntervalInMicroseconds),
0 /* flags */);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(OnTransactionAck, feedback, present_callback,
completion_callback, std::move(resources_to_release)));
}
gfx::Size GLSurfaceEGLSurfaceControl::GetSize() {
......@@ -120,13 +151,15 @@ bool GLSurfaceEGLSurfaceControl::ScheduleOverlayPlane(
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) {
DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);
if (!pending_transaction_)
pending_transaction_.emplace();
bool uninitialized = false;
if (pending_surfaces_count_ == surface_list_.size()) {
uninitialized = true;
surface_list_.emplace_back(surface_composer_.get());
surface_list_.emplace_back(root_surface_);
}
pending_surfaces_count_++;
auto& surface_state = surface_list_.at(pending_surfaces_count_ - 1);
......@@ -136,11 +169,6 @@ bool GLSurfaceEGLSurfaceControl::ScheduleOverlayPlane(
pending_transaction_->SetZOrder(surface_state.surface, z_order);
}
if (uninitialized || surface_state.transform != transform) {
surface_state.transform = transform;
// TODO(khushalsagar): Forward the transform once the NDK API is in place.
}
AHardwareBuffer* hardware_buffer = nullptr;
base::ScopedFD fence_fd;
auto scoped_hardware_buffer = image->GetAHardwareBuffer();
......@@ -167,21 +195,24 @@ bool GLSurfaceEGLSurfaceControl::ScheduleOverlayPlane(
if (uninitialized || surface_state.bounds_rect != bounds_rect) {
surface_state.bounds_rect = bounds_rect;
pending_transaction_->SetPosition(surface_state.surface, bounds_rect.x(),
bounds_rect.y());
pending_transaction_->SetSize(surface_state.surface, bounds_rect.width(),
bounds_rect.height());
pending_transaction_->SetDisplayFrame(surface_state.surface, bounds_rect);
}
// TODO(khushalsagar): Currently the framework refuses to the draw the buffer
// if the crop rect doesn't exactly match the buffer size. Update when fixed.
/*gfx::Rect enclosed_crop_rect = gfx::ToEnclosedRect(crop_rect);
if (uninitialized || surface_state.crop_rect != enclosed_crop_rect) {
surface_state.crop_rect = enclosed_crop_rect;
pending_transaction_->SetCropRect(
surface_state.surface, enclosed_crop_rect.x(), enclosed_crop_rect.y(),
enclosed_crop_rect.right(), enclosed_crop_rect.bottom());
}*/
gfx::Rect enclosed_crop_rect;
if (hardware_buffer) {
gfx::Size buffer_size = GetBufferSize(hardware_buffer);
gfx::RectF scaled_rect =
gfx::RectF(crop_rect.x() * buffer_size.width(),
crop_rect.y() * buffer_size.height(),
crop_rect.width() * buffer_size.width(),
crop_rect.height() * buffer_size.height());
enclosed_crop_rect = gfx::ToEnclosedRect(scaled_rect);
if (uninitialized || surface_state.crop_rect != enclosed_crop_rect) {
surface_state.crop_rect = enclosed_crop_rect;
pending_transaction_->SetCropRect(surface_state.surface,
enclosed_crop_rect);
}
}
bool opaque = !enable_blend;
if (uninitialized || surface_state.opaque != opaque) {
......@@ -221,22 +252,25 @@ bool GLSurfaceEGLSurfaceControl::SupportsCommitOverlayPlanes() {
return true;
}
// static
void GLSurfaceEGLSurfaceControl::OnTransactionAck(
const gfx::PresentationFeedback& feedback,
const PresentationCallback& present_callback,
const SwapCompletionCallback& completion_callback,
ResourceRefs resources) {
void GLSurfaceEGLSurfaceControl::OnTransactionAckOnGpuThread(
SwapCompletionCallback completion_callback,
PresentationCallback presentation_callback,
ResourceRefs released_resources,
int64_t present_time_ns) {
DCHECK(gpu_task_runner_->BelongsToCurrentThread());
// The presentation feedback callback must run after swap completion.
completion_callback.Run(gfx::SwapResult::SWAP_ACK, nullptr);
present_callback.Run(feedback);
resources.clear();
gfx::PresentationFeedback feedback(
base::TimeTicks::FromInternalValue(present_time_ns), base::TimeDelta(),
0 /* flags */);
presentation_callback.Run(feedback);
released_resources.clear();
}
GLSurfaceEGLSurfaceControl::SurfaceState::SurfaceState(
SurfaceComposer* composer)
: surface(composer,
SurfaceComposer::SurfaceContentType::kAHardwareBuffer,
kSurfaceName) {}
const SurfaceControl::Surface& parent)
: surface(parent, kChildSurfaceName) {}
GLSurfaceEGLSurfaceControl::SurfaceState::SurfaceState() = default;
GLSurfaceEGLSurfaceControl::SurfaceState::SurfaceState(SurfaceState&& other) =
......
......@@ -10,17 +10,24 @@
#include "base/android/scoped_hardware_buffer_handle.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "ui/gl/android/android_surface_composer_compat.h"
#include "ui/gl/android/android_surface_control_compat.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface_egl.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace gl {
class GL_EXPORT GLSurfaceEGLSurfaceControl : public gl::GLSurfaceEGL {
public:
explicit GLSurfaceEGLSurfaceControl(ANativeWindow* window);
explicit GLSurfaceEGLSurfaceControl(
ANativeWindow* window,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// GLSurface implementation.
int GetBufferCount() const override;
bool Initialize(gl::GLSurfaceFormat format) override;
void Destroy() override;
bool Resize(const gfx::Size& size,
......@@ -60,20 +67,19 @@ class GL_EXPORT GLSurfaceEGLSurfaceControl : public gl::GLSurfaceEGL {
struct SurfaceState {
SurfaceState();
explicit SurfaceState(gl::SurfaceComposer* composer);
explicit SurfaceState(const SurfaceControl::Surface& parent);
~SurfaceState();
SurfaceState(SurfaceState&& other);
SurfaceState& operator=(SurfaceState&& other);
int z_order = 0;
gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_INVALID;
AHardwareBuffer* hardware_buffer = nullptr;
gfx::Rect bounds_rect;
gfx::Rect crop_rect;
bool opaque = true;
gl::SurfaceComposer::Surface surface;
gl::SurfaceControl::Surface surface;
};
using ResourceRefs =
......@@ -83,14 +89,15 @@ class GL_EXPORT GLSurfaceEGLSurfaceControl : public gl::GLSurfaceEGL {
const SwapCompletionCallback& completion_callback,
const PresentationCallback& callback);
static void OnTransactionAck(
const gfx::PresentationFeedback& feedback,
const PresentationCallback& present_callback,
const SwapCompletionCallback& completion_callback,
ResourceRefs resources);
// Called on the |gpu_task_runner_| when a transaction is acked by the
// framework.
void OnTransactionAckOnGpuThread(SwapCompletionCallback completion_callback,
PresentationCallback presentation_callback,
ResourceRefs released_resources,
int64_t present_time_ns);
// Holds the surface state changes made since the last call to SwapBuffers.
base::Optional<gl::SurfaceComposer::Transaction> pending_transaction_;
base::Optional<gl::SurfaceControl::Transaction> pending_transaction_;
// The list of Surfaces and the corresponding state. The initial
// |pending_surfaces_count_| surfaces in this list are surfaces with state
......@@ -113,7 +120,12 @@ class GL_EXPORT GLSurfaceEGLSurfaceControl : public gl::GLSurfaceEGL {
// frame update.
ResourceRefs current_frame_resources_;
std::unique_ptr<gl::SurfaceComposer> surface_composer_;
// The root surface tied to the ANativeWindow that places the content of this
// GLSurface in the java view tree.
gl::SurfaceControl::Surface root_surface_;
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_;
base::WeakPtrFactory<GLSurfaceEGLSurfaceControl> weak_factory_;
};
} // namespace gl
......
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