summaryrefslogtreecommitdiffstats
path: root/sdm
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-05-07 20:43:43 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2018-05-07 20:43:43 -0700
commit7b1a1943052ad2134e604daf258ec30ec55f806f (patch)
treea78fec8e06027ade2114f907ad33552a3c2c122b /sdm
parent4a342c7ab0588b04ad5ccf7b7ab557025f05edc0 (diff)
parente1591472b9f413a88b87bcc4ea4972a1aeddbbf2 (diff)
downloadandroid_hardware_qcom_sdm710_display-7b1a1943052ad2134e604daf258ec30ec55f806f.tar.gz
android_hardware_qcom_sdm710_display-7b1a1943052ad2134e604daf258ec30ec55f806f.tar.bz2
android_hardware_qcom_sdm710_display-7b1a1943052ad2134e604daf258ec30ec55f806f.zip
Merge "sdm: Avoid fb_id creation and removal in each frame"
Diffstat (limited to 'sdm')
-rw-r--r--sdm/include/core/buffer_allocator.h1
-rw-r--r--sdm/include/core/layer_buffer.h6
-rw-r--r--sdm/include/core/layer_stack.h6
-rw-r--r--sdm/libs/core/display_base.cpp4
-rw-r--r--sdm/libs/core/drm/hw_device_drm.cpp168
-rw-r--r--sdm/libs/core/drm/hw_device_drm.h31
-rw-r--r--sdm/libs/core/drm/hw_peripheral_drm.cpp4
-rw-r--r--sdm/libs/core/drm/hw_virtual_drm.cpp11
-rw-r--r--sdm/libs/hwc2/hwc_buffer_allocator.cpp1
-rw-r--r--sdm/libs/hwc2/hwc_layers.cpp1
10 files changed, 138 insertions, 95 deletions
diff --git a/sdm/include/core/buffer_allocator.h b/sdm/include/core/buffer_allocator.h
index 6d77bcde..6731b770 100644
--- a/sdm/include/core/buffer_allocator.h
+++ b/sdm/include/core/buffer_allocator.h
@@ -70,6 +70,7 @@ struct AllocatedBufferInfo {
uint32_t aligned_height = 0; //!< Specifies aligned allocated buffer height in pixels.
LayerBufferFormat format = kFormatInvalid; // Specifies buffer format for allocated buffer.
uint32_t size = 0; //!< Specifies the size of the allocated buffer.
+ uint64_t id = 0; //!< Specifies the Id of the allocated buffer.
};
/*! @brief Holds the information about the input/output configuration of an output buffer.
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 649dda4a..28a7497b 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -278,6 +278,7 @@ struct LayerBuffer {
UbwcCrStatsVector ubwc_crstats[NUM_UBWC_CR_STATS_LAYERS] = {};
//! < UBWC Compression ratio,stats. Stored as a vector of pair of
//! of (tile size, #of tiles)
+ uint64_t handle_id = 0;
};
// This enum represents buffer layout types.
@@ -287,6 +288,11 @@ enum BufferLayout {
kTPTiled //!< Tightly Packed data
};
+class LayerBufferObject {
+public:
+ virtual ~LayerBufferObject() {};
+};
+
} // namespace sdm
#endif // __LAYER_BUFFER_H__
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index 3dd1c6f4..ae82bda3 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -36,6 +36,7 @@
#include <vector>
#include <utility>
+#include <unordered_map>
#include "layer_buffer.h"
#include "sdm_types.h"
@@ -304,6 +305,10 @@ struct LayerSolidFill {
uint32_t alpha = 0; //!< Alpha value
};
+struct LayerBufferMap {
+ std::unordered_map<uint64_t, std::shared_ptr<LayerBufferObject>> buffer_map;
+};
+
/*! @brief This structure defines display layer object which contains layer properties and a drawing
buffer.
@@ -376,6 +381,7 @@ struct Layer {
Lut3d lut_3d = {}; //!< o/p - Populated by SDM when tone mapping is
//!< needed on this layer.
LayerSolidFill solid_fill_info = {}; //!< solid fill info along with depth.
+ std::shared_ptr<LayerBufferMap> buffer_map = nullptr; //!< Map of handle_id and fb_id.
};
/*! @brief This structure defines a layer stack that contains layers which need to be composed and
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index a50dd944..0422b586 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -150,6 +150,9 @@ DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
hw_layers_info.stack = layer_stack;
for (auto &layer : layers) {
+ if (layer->buffer_map == nullptr) {
+ layer->buffer_map = std::make_shared<LayerBufferMap>();
+ }
if (layer->composition == kCompositionGPUTarget) {
hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count;
break;
@@ -1362,6 +1365,7 @@ void DisplayBase::CommitLayerParams(LayerStack *layer_stack) {
hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
+ hw_layer.input_buffer.handle_id = sdm_layer->input_buffer.handle_id;
}
return;
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 81237389..8c8faf3a 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -222,25 +222,31 @@ static void GetDRMFormat(LayerBufferFormat format, uint32_t *drm_format,
}
}
-HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
- buffer_allocator_(buffer_allocator) {
- DRMMaster *master = nullptr;
- DRMMaster::GetInstance(&master);
-
- if (!master) {
- DLOGE("Failed to acquire DRM Master instance");
- return;
+class FrameBufferObject : public LayerBufferObject {
+ public:
+ FrameBufferObject(uint32_t fb_id) : fb_id_(fb_id) {
}
- // If RMFB is ref-counted, we should immediately make a call to clean up fb_id after commit.
- // Driver will release fb_id after its usage. Otherwise speculatively free up fb_id after 3
- // cycles assuming driver is done with it.
- rmfb_delay_ = master->IsRmFbRefCounted() ? 1 : 3;
- hashmap_ = new std::unordered_map<int, uint32_t>[rmfb_delay_];
-}
+ ~FrameBufferObject() {
+ DRMMaster *master;
+ DRMMaster::GetInstance(&master);
+ int ret = master->RemoveFbId(fb_id_);
+ if (ret < 0) {
+ DLOGE("Removing fb_id %d failed with error %d", fb_id_, errno);
+ }
+ };
+ uint32_t GetFbId() { return fb_id_; }
+
+ private:
+ uint32_t fb_id_;
+};
-HWDeviceDRM::Registry::~Registry() {
- delete [] hashmap_;
+HWDeviceDRM::Registry::Registry(BufferAllocator *buffer_allocator) :
+ buffer_allocator_(buffer_allocator) {
+ int value = 0;
+ if (Debug::GetProperty(DISABLE_FBID_CACHE, &value) == kErrorNone) {
+ disable_fbid_cache_ = (value == 1);
+ }
}
void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) {
@@ -257,79 +263,105 @@ void HWDeviceDRM::Registry::Register(HWLayers *hw_layers) {
input_buffer = &hw_rotator_session->output_buffer;
}
- MapBufferToFbId(input_buffer);
+ MapBufferToFbId(&layer, input_buffer);
}
}
-void HWDeviceDRM::Registry::MapBufferToFbId(LayerBuffer* buffer) {
- int fd = buffer->planes[0].fd;
+int HWDeviceDRM::Registry::CreateFbId(LayerBuffer *buffer, uint32_t *fb_id) {
DRMMaster *master = nullptr;
DRMMaster::GetInstance(&master);
+ int ret = -1;
if (!master) {
DLOGE("Failed to acquire DRM Master instance");
+ return ret;
+ }
+
+ DRMBuffer layout{};
+ AllocatedBufferInfo buf_info{};
+ buf_info.fd = layout.fd = buffer->planes[0].fd;
+ buf_info.aligned_width = layout.width = buffer->width;
+ buf_info.aligned_height = layout.height = buffer->height;
+ buf_info.format = buffer->format;
+ GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
+ buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset, &layout.num_planes);
+ ret = master->CreateFbId(layout, fb_id);
+ if (ret < 0) {
+ DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
+ layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0], errno);
+ }
+
+ return ret;
+}
+
+void HWDeviceDRM::Registry::MapBufferToFbId(Layer* layer, LayerBuffer* buffer) {
+ if (buffer->planes[0].fd < 0) {
return;
}
- if (fd >= 0 && hashmap_[current_index_].find(fd) == hashmap_[current_index_].end()) {
- AllocatedBufferInfo buf_info{};
- DRMBuffer layout{};
- buf_info.fd = layout.fd = fd;
- buf_info.aligned_width = layout.width = buffer->width;
- buf_info.aligned_height = layout.height = buffer->height;
- buf_info.format = buffer->format;
- GetDRMFormat(buf_info.format, &layout.drm_format, &layout.drm_format_modifier);
- buffer_allocator_->GetBufferLayout(buf_info, layout.stride, layout.offset,
- &layout.num_planes);
- uint32_t fb_id = 0;
- int ret = master->CreateFbId(layout, &fb_id);
- if (ret < 0) {
- DLOGE("CreateFbId failed. width %d, height %d, format: %s, stride %u, error %d",
- layout.width, layout.height, GetFormatString(buf_info.format), layout.stride[0],
- errno);
- } else {
- hashmap_[current_index_][fd] = fb_id;
- }
+ uint64_t handle_id = buffer->handle_id;
+
+ if (!handle_id || disable_fbid_cache_) {
+ // Legacy: Remove & Create fb_id in each frame
+ layer->buffer_map->buffer_map.clear();
}
- return;
-}
-void HWDeviceDRM::Registry::Next() {
- current_index_ = (current_index_ + 1) % rmfb_delay_;
-}
+ if (layer->buffer_map->buffer_map.find(handle_id) != layer->buffer_map->buffer_map.end()) {
+ // Found fb_id for given handle_id key
+ return;
+ }
-void HWDeviceDRM::Registry::Unregister() {
- DRMMaster *master = nullptr;
- DRMMaster::GetInstance(&master);
+ uint32_t fb_id = 0;
+ if (CreateFbId(buffer, &fb_id) >= 0) {
+ // Create and cache the fb_id in map
+ layer->buffer_map->buffer_map[handle_id] = std::make_shared<FrameBufferObject>(fb_id);
+ }
+}
- if (!master) {
- DLOGE("Failed to acquire DRM Master instance");
+void HWDeviceDRM::Registry::MapOutputBufferToFbId(LayerBuffer *output_buffer) {
+ if (output_buffer->planes[0].fd < 0) {
return;
}
- auto &curr_map = hashmap_[current_index_];
- for (auto &pair : curr_map) {
- uint32_t fb_id = pair.second;
- int ret = master->RemoveFbId(fb_id);
- if (ret < 0) {
- DLOGE("Removing fb_id %d failed with error %d", fb_id, errno);
- }
+ uint64_t handle_id = output_buffer->handle_id;
+
+ if (!handle_id || disable_fbid_cache_) {
+ // Legacy: Remove & Create fb_id in each frame
+ output_buffer_map_.clear();
+ }
+
+ if (output_buffer_map_.find(handle_id) != output_buffer_map_.end()) {
+ return;
}
- curr_map.clear();
+ uint32_t fb_id = 0;
+ if (CreateFbId(output_buffer, &fb_id) >= 0) {
+ output_buffer_map_[handle_id] = std::make_shared<FrameBufferObject>(fb_id);
+ }
}
void HWDeviceDRM::Registry::Clear() {
- for (int i = 0; i < rmfb_delay_; i++) {
- Unregister();
- Next();
+ output_buffer_map_.clear();
+}
+
+uint32_t HWDeviceDRM::Registry::GetFbId(Layer *layer, uint64_t handle_id) {
+ auto it = layer->buffer_map->buffer_map.find(handle_id);
+ if (it != layer->buffer_map->buffer_map.end()) {
+ FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
+ return fb_obj->GetFbId();
}
- current_index_ = 0;
+
+ return 0;
}
-uint32_t HWDeviceDRM::Registry::GetFbId(int fd) {
- auto it = hashmap_[current_index_].find(fd);
- return (it == hashmap_[current_index_].end()) ? 0 : it->second;
+uint32_t HWDeviceDRM::Registry::GetOutputFbId(uint64_t handle_id) {
+ auto it = output_buffer_map_.find(handle_id);
+ if (it != output_buffer_map_.end()) {
+ FrameBufferObject *fb_obj = static_cast<FrameBufferObject*>(it->second.get());
+ return fb_obj->GetFbId();
+ }
+
+ return 0;
}
HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
@@ -853,7 +885,8 @@ void HWDeviceDRM::SetupAtomic(HWLayers *hw_layers, bool validate) {
input_buffer = &hw_rotator_session->output_buffer;
}
- uint32_t fb_id = registry_.GetFbId(input_buffer->planes[0].fd);
+ uint32_t fb_id = registry_.GetFbId(&layer, input_buffer->handle_id);
+
if (pipe_info->valid && fb_id) {
uint32_t pipe_id = pipe_info->pipe_id;
drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ALPHA, pipe_id, layer.plane_alpha);
@@ -1020,7 +1053,6 @@ DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
err = kErrorHardware;
}
- registry_.Unregister();
return err;
}
@@ -1036,9 +1068,6 @@ DisplayError HWDeviceDRM::Commit(HWLayers *hw_layers) {
err = AtomicCommit(hw_layers);
}
- registry_.Next();
- registry_.Unregister();
-
return err;
}
@@ -1079,7 +1108,8 @@ DisplayError HWDeviceDRM::DefaultCommit(HWLayers *hw_layers) {
drmModeModeInfo mode;
res_mgr->GetMode(&mode);
- uint32_t fb_id = registry_.GetFbId(hw_layer_info.hw_layers.at(0).input_buffer.planes[0].fd);
+ uint64_t handle_id = hw_layer_info.hw_layers.at(0).input_buffer.handle_id;
+ uint32_t fb_id = registry_.GetFbId(&hw_layer_info.hw_layers.at(0), handle_id);
ret = drmModeSetCrtc(dev_fd, crtc_id, fb_id, 0 /* x */, 0 /* y */, &connector_id,
1 /* num_connectors */, &mode);
if (ret < 0) {
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 1419d9fd..02389470 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -138,27 +138,24 @@ class HWDeviceDRM : public HWInterface {
class Registry {
public:
explicit Registry(BufferAllocator *buffer_allocator);
- ~Registry();
- // Called on each Validate and Commit to register layer buffers fds to the slot pointed to by
- // current_index_
+ // Called on each Validate and Commit to map the handle_id to fb_id of each layer buffer.
void Register(HWLayers *hw_layers);
- // Clears the slot pointed to by current_index_
- void Unregister();
- // Moves current_index_ to the next position
- void Next();
- // Called on display disconnect to release all gem handles and fb_ids
+ // Called on display disconnect to clear output buffer map and remove fb_ids.
void Clear();
- // Maps given fd to FB ID
- void MapBufferToFbId(LayerBuffer* buffer);
- // Finds an fb_id corresponding to an fd in current map
- uint32_t GetFbId(int fd);
+ // Create the fd_id for the given buffer.
+ int CreateFbId(LayerBuffer *buffer, uint32_t *fb_id);
+ // Find handle_id in the layer map. Else create fb_id and add <handle_id,fb_id> in map.
+ void MapBufferToFbId(Layer* layer, LayerBuffer* buffer);
+ // Find handle_id in output buffer map. Else create fb_id and add <handle_id,fb_id> in map.
+ void MapOutputBufferToFbId(LayerBuffer* buffer);
+ // Find fb_id for given handle_id in the layer map.
+ uint32_t GetFbId(Layer *layer, uint64_t handle_id);
+ // Find fb_id for given handle_id in output buffer map.
+ uint32_t GetOutputFbId(uint64_t handle_id);
private:
- uint8_t rmfb_delay_ = 1; // N cycle delay before destroy
- // fd to fb_id map. fd is used as key only for a single draw cycle between
- // prepare and commit. It should not be used for caching in future due to fd recycling
- std::unordered_map<int, uint32_t> *hashmap_ {};
- int current_index_ = 0;
+ bool disable_fbid_cache_ = false;
+ std::unordered_map<uint64_t, std::shared_ptr<LayerBufferObject>> output_buffer_map_ {};
BufferAllocator *buffer_allocator_ = {};
};
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index dbd707f9..87c99495 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -200,7 +200,7 @@ DisplayError HWPeripheralDRM::SetupConcurrentWritebackModes() {
void HWPeripheralDRM::ConfigureConcurrentWriteback(LayerStack *layer_stack) {
LayerBuffer *output_buffer = layer_stack->output_buffer;
- registry_.MapBufferToFbId(output_buffer);
+ registry_.MapOutputBufferToFbId(output_buffer);
// Set the topology for Concurrent Writeback: [CRTC_PRIMARY_DISPLAY - CONNECTOR_VIRTUAL_DISPLAY].
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, cwb_config_.token.conn_id, token_.crtc_id);
@@ -211,7 +211,7 @@ void HWPeripheralDRM::ConfigureConcurrentWriteback(LayerStack *layer_stack) {
drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CAPTURE_MODE, token_.crtc_id, capture_mode);
// Set Connector Output FB
- uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
+ uint32_t fb_id = registry_.GetOutputFbId(output_buffer->handle_id);
drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_FB_ID, cwb_config_.token.conn_id, fb_id);
// Set Connector Secure Mode
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
index 29367fee..a2e84a29 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -126,8 +126,8 @@ DisplayError HWVirtualDRM::Commit(HWLayers *hw_layers) {
DisplayError err = kErrorNone;
registry_.Register(hw_layers);
- registry_.MapBufferToFbId(output_buffer);
- uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
+ registry_.MapOutputBufferToFbId(output_buffer);
+ uint32_t fb_id = registry_.GetOutputFbId(output_buffer->handle_id);
ConfigureWbConnectorFbId(fb_id);
ConfigureWbConnectorDestRect();
@@ -138,17 +138,14 @@ DisplayError HWVirtualDRM::Commit(HWLayers *hw_layers) {
DLOGE("Atomic commit failed for crtc_id %d conn_id %d", token_.crtc_id, token_.conn_id);
}
- registry_.Next();
- registry_.Unregister();
-
return(err);
}
DisplayError HWVirtualDRM::Validate(HWLayers *hw_layers) {
LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
- registry_.MapBufferToFbId(output_buffer);
- uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
+ registry_.MapOutputBufferToFbId(output_buffer);
+ uint32_t fb_id = registry_.GetOutputFbId(output_buffer->handle_id);
ConfigureWbConnectorFbId(fb_id);
ConfigureWbConnectorDestRect();
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index e1d32db4..24e9227b 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -144,6 +144,7 @@ DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
alloc_buffer_info->aligned_width = UINT32(hnd->width);
alloc_buffer_info->aligned_height = UINT32(hnd->height);
alloc_buffer_info->size = hnd->size;
+ alloc_buffer_info->id = hnd->id;
buffer_info->private_data = reinterpret_cast<void *>(hnd);
return kErrorNone;
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 4250335e..6dcfa233 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -264,6 +264,7 @@ HWC2::Error HWCLayer::SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fen
layer_buffer->planes[0].stride = UINT32(handle->width);
layer_buffer->size = handle->size;
layer_buffer->buffer_id = reinterpret_cast<uint64_t>(handle);
+ layer_buffer->handle_id = handle->id;
return HWC2::Error::None;
}