forked from suyu/suyu
nvnflinger/vi: don't recreate buffer queue on open/close
This commit is contained in:
parent
d1eaeeed8c
commit
9f159dd62c
8 changed files with 88 additions and 72 deletions
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
|
#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
|
||||||
#include "core/hle/service/nvnflinger/hwc_layer.h"
|
#include "core/hle/service/nvnflinger/hwc_layer.h"
|
||||||
|
|
||||||
|
@ -26,18 +24,12 @@ struct Layer {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LayerStack {
|
struct LayerStack {
|
||||||
std::list<Layer> layers;
|
std::vector<std::shared_ptr<Layer>> layers;
|
||||||
};
|
|
||||||
|
|
||||||
struct Display {
|
std::shared_ptr<Layer> FindLayer(s32 consumer_id) {
|
||||||
explicit Display(u64 id_) {
|
for (auto& layer : layers) {
|
||||||
id = id_;
|
if (layer->consumer_id == consumer_id) {
|
||||||
}
|
return layer;
|
||||||
|
|
||||||
Layer* FindLayer(s32 consumer_id) {
|
|
||||||
for (auto& layer : stack.layers) {
|
|
||||||
if (layer.consumer_id == consumer_id) {
|
|
||||||
return &layer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +37,13 @@ struct Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasLayers() {
|
bool HasLayers() {
|
||||||
return !stack.layers.empty();
|
return !layers.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Display {
|
||||||
|
explicit Display(u64 id_) {
|
||||||
|
id = id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 id;
|
u64 id;
|
||||||
|
|
|
@ -55,10 +55,10 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
||||||
|
|
||||||
// Acquire all necessary framebuffers.
|
// Acquire all necessary framebuffers.
|
||||||
for (auto& layer : display.stack.layers) {
|
for (auto& layer : display.stack.layers) {
|
||||||
auto consumer_id = layer.consumer_id;
|
auto consumer_id = layer->consumer_id;
|
||||||
|
|
||||||
// Try to fetch the framebuffer (either new or stale).
|
// Try to fetch the framebuffer (either new or stale).
|
||||||
const auto result = this->CacheFramebufferLocked(layer, consumer_id);
|
const auto result = this->CacheFramebufferLocked(*layer, consumer_id);
|
||||||
|
|
||||||
// If we failed, skip this layer.
|
// If we failed, skip this layer.
|
||||||
if (result == CacheStatus::NoBufferAvailable) {
|
if (result == CacheStatus::NoBufferAvailable) {
|
||||||
|
@ -75,7 +75,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
||||||
const auto& igbp_buffer = *item.graphic_buffer;
|
const auto& igbp_buffer = *item.graphic_buffer;
|
||||||
|
|
||||||
// TODO: get proper Z-index from layer
|
// TODO: get proper Z-index from layer
|
||||||
if (layer.visible) {
|
if (layer->visible) {
|
||||||
composition_stack.emplace_back(HwcLayer{
|
composition_stack.emplace_back(HwcLayer{
|
||||||
.buffer_handle = igbp_buffer.BufferId(),
|
.buffer_handle = igbp_buffer.BufferId(),
|
||||||
.offset = igbp_buffer.Offset(),
|
.offset = igbp_buffer.Offset(),
|
||||||
|
@ -84,7 +84,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
||||||
.height = igbp_buffer.Height(),
|
.height = igbp_buffer.Height(),
|
||||||
.stride = igbp_buffer.Stride(),
|
.stride = igbp_buffer.Stride(),
|
||||||
.z_index = 0,
|
.z_index = 0,
|
||||||
.blending = layer.blending,
|
.blending = layer->blending,
|
||||||
.transform = static_cast<android::BufferTransformFlags>(item.transform),
|
.transform = static_cast<android::BufferTransformFlags>(item.transform),
|
||||||
.crop_rect = item.crop,
|
.crop_rect = item.crop,
|
||||||
.acquire_fence = item.fence,
|
.acquire_fence = item.fence,
|
||||||
|
@ -134,7 +134,7 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* layer = display.FindLayer(layer_id); layer != nullptr) {
|
if (const auto layer = display.stack.FindLayer(layer_id); layer != nullptr) {
|
||||||
// TODO: support release fence
|
// TODO: support release fence
|
||||||
// This is needed to prevent screen tearing
|
// This is needed to prevent screen tearing
|
||||||
layer->buffer_item_consumer->ReleaseBuffer(framebuffer.item, android::Fence::NoFence());
|
layer->buffer_item_consumer->ReleaseBuffer(framebuffer.item, android::Fence::NoFence());
|
||||||
|
@ -153,7 +153,7 @@ void HardwareComposer::RemoveLayerLocked(Display& display, ConsumerId consumer_i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to release the buffer item.
|
// Try to release the buffer item.
|
||||||
auto* const layer = display.FindLayer(consumer_id);
|
const auto layer = display.stack.FindLayer(consumer_id);
|
||||||
if (layer && it->second.is_acquired) {
|
if (layer && it->second.is_acquired) {
|
||||||
layer->buffer_item_consumer->ReleaseBuffer(it->second.item, android::Fence::NoFence());
|
layer->buffer_item_consumer->ReleaseBuffer(it->second.item, android::Fence::NoFence());
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ void SurfaceFlinger::RemoveDisplay(u64 display_id) {
|
||||||
bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
|
bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
|
||||||
u64 display_id) {
|
u64 display_id) {
|
||||||
auto* const display = this->FindDisplay(display_id);
|
auto* const display = this->FindDisplay(display_id);
|
||||||
if (!display || !display->HasLayers()) {
|
if (!display || !display->stack.HasLayers()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,19 +46,34 @@ bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_spe
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
|
void SurfaceFlinger::CreateLayer(s32 consumer_binder_id) {
|
||||||
auto* const display = this->FindDisplay(display_id);
|
|
||||||
auto binder = std::static_pointer_cast<android::BufferQueueConsumer>(
|
auto binder = std::static_pointer_cast<android::BufferQueueConsumer>(
|
||||||
m_server.TryGetBinder(consumer_binder_id));
|
m_server.TryGetBinder(consumer_binder_id));
|
||||||
|
if (!binder) {
|
||||||
if (!display || !binder) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder));
|
auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(binder));
|
||||||
buffer_item_consumer->Connect(false);
|
buffer_item_consumer->Connect(false);
|
||||||
|
|
||||||
display->stack.layers.emplace_back(std::move(buffer_item_consumer), consumer_binder_id);
|
m_layers.layers.emplace_back(
|
||||||
|
std::make_shared<Layer>(std::move(buffer_item_consumer), consumer_binder_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::DestroyLayer(s32 consumer_binder_id) {
|
||||||
|
std::erase_if(m_layers.layers,
|
||||||
|
[&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
|
||||||
|
auto* const display = this->FindDisplay(display_id);
|
||||||
|
auto layer = this->FindLayer(consumer_binder_id);
|
||||||
|
|
||||||
|
if (!display || !layer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->stack.layers.emplace_back(std::move(layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) {
|
void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id) {
|
||||||
|
@ -69,18 +84,18 @@ void SurfaceFlinger::RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_bi
|
||||||
|
|
||||||
m_composer.RemoveLayerLocked(*display, consumer_binder_id);
|
m_composer.RemoveLayerLocked(*display, consumer_binder_id);
|
||||||
std::erase_if(display->stack.layers,
|
std::erase_if(display->stack.layers,
|
||||||
[&](auto& layer) { return layer.consumer_id == consumer_binder_id; });
|
[&](auto& layer) { return layer->consumer_id == consumer_binder_id; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) {
|
void SurfaceFlinger::SetLayerVisibility(s32 consumer_binder_id, bool visible) {
|
||||||
if (auto* layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
|
if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
|
||||||
layer->visible = visible;
|
layer->visible = visible;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) {
|
void SurfaceFlinger::SetLayerBlending(s32 consumer_binder_id, LayerBlending blending) {
|
||||||
if (auto* layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
|
if (const auto layer = this->FindLayer(consumer_binder_id); layer != nullptr) {
|
||||||
layer->blending = blending;
|
layer->blending = blending;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,9 +111,9 @@ Display* SurfaceFlinger::FindDisplay(u64 display_id) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer* SurfaceFlinger::FindLayer(s32 consumer_binder_id) {
|
std::shared_ptr<Layer> SurfaceFlinger::FindLayer(s32 consumer_binder_id) {
|
||||||
for (auto& display : m_displays) {
|
for (auto& layer : m_layers.layers) {
|
||||||
if (auto* layer = display.FindLayer(consumer_binder_id); layer != nullptr) {
|
if (layer->consumer_id == consumer_binder_id) {
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,9 @@ public:
|
||||||
void RemoveDisplay(u64 display_id);
|
void RemoveDisplay(u64 display_id);
|
||||||
bool ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
|
bool ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
|
||||||
|
|
||||||
|
void CreateLayer(s32 consumer_binder_id);
|
||||||
|
void DestroyLayer(s32 consumer_binder_id);
|
||||||
|
|
||||||
void AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id);
|
void AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id);
|
||||||
void RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id);
|
void RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id);
|
||||||
|
|
||||||
|
@ -44,7 +47,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Display* FindDisplay(u64 display_id);
|
Display* FindDisplay(u64 display_id);
|
||||||
Layer* FindLayer(s32 consumer_binder_id);
|
std::shared_ptr<Layer> FindLayer(s32 consumer_binder_id);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// TODO: these don't belong here
|
// TODO: these don't belong here
|
||||||
|
@ -57,6 +60,7 @@ private:
|
||||||
KernelHelpers::ServiceContext m_context;
|
KernelHelpers::ServiceContext m_context;
|
||||||
|
|
||||||
std::vector<Display> m_displays;
|
std::vector<Display> m_displays;
|
||||||
|
LayerStack m_layers;
|
||||||
std::shared_ptr<Nvidia::Module> nvdrv;
|
std::shared_ptr<Nvidia::Module> nvdrv;
|
||||||
s32 disp_fd;
|
s32 disp_fd;
|
||||||
HardwareComposer m_composer;
|
HardwareComposer m_composer;
|
||||||
|
|
|
@ -43,11 +43,7 @@ void Container::OnTerminate() {
|
||||||
|
|
||||||
m_is_shut_down = true;
|
m_is_shut_down = true;
|
||||||
|
|
||||||
m_layers.ForEachLayer([&](auto& layer) {
|
m_layers.ForEachLayer([&](auto& layer) { this->DestroyLayerLocked(layer.GetId()); });
|
||||||
if (layer.IsOpen()) {
|
|
||||||
this->DestroyBufferQueueLocked(&layer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
m_displays.ForEachDisplay(
|
m_displays.ForEachDisplay(
|
||||||
[&](auto& display) { m_surface_flinger->RemoveDisplay(display.GetId()); });
|
[&](auto& display) { m_surface_flinger->RemoveDisplay(display.GetId()); });
|
||||||
|
@ -161,16 +157,29 @@ Result Container::CreateLayerLocked(u64* out_layer_id, u64 display_id, u64 owner
|
||||||
auto* const display = m_displays.GetDisplayById(display_id);
|
auto* const display = m_displays.GetDisplayById(display_id);
|
||||||
R_UNLESS(display != nullptr, VI::ResultNotFound);
|
R_UNLESS(display != nullptr, VI::ResultNotFound);
|
||||||
|
|
||||||
auto* const layer = m_layers.CreateLayer(owner_aruid, display);
|
s32 consumer_binder_id, producer_binder_id;
|
||||||
|
m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id);
|
||||||
|
|
||||||
|
auto* const layer =
|
||||||
|
m_layers.CreateLayer(owner_aruid, display, consumer_binder_id, producer_binder_id);
|
||||||
R_UNLESS(layer != nullptr, VI::ResultNotFound);
|
R_UNLESS(layer != nullptr, VI::ResultNotFound);
|
||||||
|
|
||||||
|
m_surface_flinger->CreateLayer(consumer_binder_id);
|
||||||
|
|
||||||
*out_layer_id = layer->GetId();
|
*out_layer_id = layer->GetId();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Container::DestroyLayerLocked(u64 layer_id) {
|
Result Container::DestroyLayerLocked(u64 layer_id) {
|
||||||
R_SUCCEED_IF(m_layers.DestroyLayer(layer_id));
|
auto* const layer = m_layers.GetLayerById(layer_id);
|
||||||
R_THROW(VI::ResultNotFound);
|
R_UNLESS(layer != nullptr, VI::ResultNotFound);
|
||||||
|
|
||||||
|
m_surface_flinger->DestroyLayer(layer->GetConsumerBinderId());
|
||||||
|
m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(),
|
||||||
|
layer->GetProducerBinderId());
|
||||||
|
m_layers.DestroyLayer(layer_id);
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid) {
|
Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid) {
|
||||||
|
@ -181,7 +190,12 @@ Result Container::OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64
|
||||||
R_UNLESS(!layer->IsOpen(), VI::ResultOperationFailed);
|
R_UNLESS(!layer->IsOpen(), VI::ResultOperationFailed);
|
||||||
R_UNLESS(layer->GetOwnerAruid() == aruid, VI::ResultPermissionDenied);
|
R_UNLESS(layer->GetOwnerAruid() == aruid, VI::ResultPermissionDenied);
|
||||||
|
|
||||||
this->CreateBufferQueueLocked(layer);
|
layer->Open();
|
||||||
|
|
||||||
|
if (auto* display = layer->GetDisplay(); display != nullptr) {
|
||||||
|
m_surface_flinger->AddLayerToDisplayStack(display->GetId(), layer->GetConsumerBinderId());
|
||||||
|
}
|
||||||
|
|
||||||
*out_producer_binder_id = layer->GetProducerBinderId();
|
*out_producer_binder_id = layer->GetProducerBinderId();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
@ -192,30 +206,14 @@ Result Container::CloseLayerLocked(u64 layer_id) {
|
||||||
R_UNLESS(layer != nullptr, VI::ResultNotFound);
|
R_UNLESS(layer != nullptr, VI::ResultNotFound);
|
||||||
R_UNLESS(layer->IsOpen(), VI::ResultOperationFailed);
|
R_UNLESS(layer->IsOpen(), VI::ResultOperationFailed);
|
||||||
|
|
||||||
this->DestroyBufferQueueLocked(layer);
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Container::CreateBufferQueueLocked(Layer* layer) {
|
|
||||||
s32 consumer_binder_id, producer_binder_id;
|
|
||||||
m_surface_flinger->CreateBufferQueue(&consumer_binder_id, &producer_binder_id);
|
|
||||||
layer->Open(consumer_binder_id, producer_binder_id);
|
|
||||||
|
|
||||||
if (auto* display = layer->GetDisplay(); display != nullptr) {
|
|
||||||
m_surface_flinger->AddLayerToDisplayStack(display->GetId(), consumer_binder_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Container::DestroyBufferQueueLocked(Layer* layer) {
|
|
||||||
if (auto* display = layer->GetDisplay(); display != nullptr) {
|
if (auto* display = layer->GetDisplay(); display != nullptr) {
|
||||||
m_surface_flinger->RemoveLayerFromDisplayStack(display->GetId(),
|
m_surface_flinger->RemoveLayerFromDisplayStack(display->GetId(),
|
||||||
layer->GetConsumerBinderId());
|
layer->GetConsumerBinderId());
|
||||||
}
|
}
|
||||||
|
|
||||||
layer->Close();
|
layer->Close();
|
||||||
m_surface_flinger->DestroyBufferQueue(layer->GetConsumerBinderId(),
|
|
||||||
layer->GetProducerBinderId());
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
|
bool Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
|
||||||
|
|
|
@ -72,9 +72,6 @@ private:
|
||||||
Result OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid);
|
Result OpenLayerLocked(s32* out_producer_binder_id, u64 layer_id, u64 aruid);
|
||||||
Result CloseLayerLocked(u64 layer_id);
|
Result CloseLayerLocked(u64 layer_id);
|
||||||
|
|
||||||
void CreateBufferQueueLocked(Layer* layer);
|
|
||||||
void DestroyBufferQueueLocked(Layer* layer);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
|
bool ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
|
||||||
|
|
||||||
|
|
|
@ -13,29 +13,31 @@ class Layer {
|
||||||
public:
|
public:
|
||||||
constexpr Layer() = default;
|
constexpr Layer() = default;
|
||||||
|
|
||||||
void Initialize(u64 id, u64 owner_aruid, Display* display) {
|
void Initialize(u64 id, u64 owner_aruid, Display* display, s32 consumer_binder_id,
|
||||||
|
s32 producer_binder_id) {
|
||||||
m_id = id;
|
m_id = id;
|
||||||
m_owner_aruid = owner_aruid;
|
m_owner_aruid = owner_aruid;
|
||||||
m_display = display;
|
m_display = display;
|
||||||
|
m_consumer_binder_id = consumer_binder_id;
|
||||||
|
m_producer_binder_id = producer_binder_id;
|
||||||
m_is_initialized = true;
|
m_is_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Finalize() {
|
void Finalize() {
|
||||||
m_id = {};
|
m_id = {};
|
||||||
|
m_owner_aruid = {};
|
||||||
m_display = {};
|
m_display = {};
|
||||||
|
m_consumer_binder_id = {};
|
||||||
|
m_producer_binder_id = {};
|
||||||
m_is_initialized = {};
|
m_is_initialized = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Open(s32 consumer_binder_id, s32 producer_binder_id) {
|
void Open() {
|
||||||
m_consumer_binder_id = consumer_binder_id;
|
|
||||||
m_producer_binder_id = producer_binder_id;
|
|
||||||
m_is_open = true;
|
m_is_open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
m_producer_binder_id = {};
|
m_is_open = false;
|
||||||
m_consumer_binder_id = {};
|
|
||||||
m_is_open = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetId() const {
|
u64 GetId() const {
|
||||||
|
|
|
@ -11,13 +11,15 @@ class LayerList {
|
||||||
public:
|
public:
|
||||||
constexpr LayerList() = default;
|
constexpr LayerList() = default;
|
||||||
|
|
||||||
Layer* CreateLayer(u64 owner_aruid, Display* display) {
|
Layer* CreateLayer(u64 owner_aruid, Display* display, s32 consumer_binder_id,
|
||||||
|
s32 producer_binder_id) {
|
||||||
Layer* const layer = GetFreeLayer();
|
Layer* const layer = GetFreeLayer();
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer->Initialize(++m_next_id, owner_aruid, display);
|
layer->Initialize(++m_next_id, owner_aruid, display, consumer_binder_id,
|
||||||
|
producer_binder_id);
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue