purged_gl_resources, purged_media_resources, &has_gpu_resource);
size_t purged_size = purged_gl_resources.size();
- FrameBufferManager *pFBManager = FrameBufferManager::GetInstance(gpu_fd_);
+ FrameBufferManager *pFBManager = FrameBufferManager::GetInstance();
if (purged_size != 0) {
if (has_gpu_resource) {
for (size_t i = 0; i < purged_size; i++) {
const ResourceHandle &handle = purged_gl_resources.at(i);
- bool fd_created = false;
- if (handle.drm_fd_)
- fd_created = true;
-
- if (fd_created &&
- pFBManager->RemoveFB(handle.drm_fd_,
- handler->CanReleaseGemHandles(handle.handle_))) {
- ETRACE("Failed to remove fb %s", PRINTERROR());
- }
-
if (!handle.handle_) {
continue;
}
- handler->ReleaseBuffer(handle.handle_, !fd_created);
+ pFBManager->RemoveFB(handle.handle_->meta_data_.num_planes_,
+ handle.handle_->meta_data_.gem_handles_);
+
+ handler->ReleaseBuffer(handle.handle_);
handler->DestroyHandle(handle.handle_);
}
}
for (size_t i = 0; i < purged_size; i++) {
const MediaResourceHandle &handle = purged_media_resources.at(i);
- if (handle.drm_fd_ &&
- pFBManager->RemoveFB(handle.drm_fd_,
- handler->CanReleaseGemHandles(handle.handle_))) {
- ETRACE("Failed to remove fb %s", PRINTERROR());
- }
-
if (!handle.handle_) {
continue;
}
+ pFBManager->RemoveFB(handle.handle_->meta_data_.num_planes_,
+ handle.handle_->meta_data_.gem_handles_);
handler->ReleaseBuffer(handle.handle_);
handler->DestroyHandle(handle.handle_);
}
FrameBufferManager *FrameBufferManager::pInstance = NULL;
-FrameBufferManager *FrameBufferManager::GetInstance(uint32_t gpu_fd) {
+FrameBufferManager *FrameBufferManager::GetInstance() {
+ return pInstance;
+}
+
+void FrameBufferManager::CreateInstance(uint32_t gpu_fd) {
if (pInstance == NULL)
pInstance = new FrameBufferManager(gpu_fd);
- return pInstance;
+}
+
+void FrameBufferManager::RegisterGemHandles(const uint32_t &num_planes,
+ const uint32_t (&igem_handles)[4]) {
+ lock_.lock();
+ FBKey key(num_planes, igem_handles);
+ auto it = fb_map_.find(key);
+ if (it != fb_map_.end()) {
+ it->second.fb_ref++;
+ } else {
+ FBValue value;
+ value.fb_ref = 1;
+ value.fb_id = 0;
+ value.fb_created = false;
+ fb_map_.emplace(std::make_pair(key, value));
+ }
+
+ lock_.unlock();
}
uint32_t FrameBufferManager::FindFB(const uint32_t &iwidth,
const uint32_t (&ioffsets)[4]) {
lock_.lock();
FBKey key(num_planes, igem_handles);
+ uint32_t fb_id = 0;
auto it = fb_map_.find(key);
if (it != fb_map_.end()) {
- it->second.fb_ref++;
- lock_.unlock();
- return it->second.fb_id;
- } else {
- uint32_t fb_id = 0;
- int ret =
- CreateFrameBuffer(iwidth, iheight, iframe_buffer_format, igem_handles,
- ipitches, ioffsets, gpu_fd_, &fb_id);
- if (ret) {
- lock_.unlock();
- return fb_id;
+ if (it->second.fb_created) {
+ it->second.fb_ref++;
+ } else {
+ it->second.fb_created = true;
+ CreateFrameBuffer(iwidth, iheight, iframe_buffer_format, igem_handles,
+ ipitches, ioffsets, gpu_fd_, &it->second.fb_id);
}
- FBValue value;
- value.fb_id = fb_id;
- value.fb_ref = 1;
- fb_map_.emplace(std::make_pair(key, value));
- lock_.unlock();
- return fb_id;
+ fb_id = it->second.fb_id;
+ } else {
+ ETRACE("Handle not found in Cache \n");
}
+
+ lock_.unlock();
+ return fb_id;
}
-int FrameBufferManager::RemoveFB(const uint32_t &fb, bool release_gem_handles) {
+int FrameBufferManager::RemoveFB(uint32_t num_planes,
+ const uint32_t (&igem_handles)[4]) {
lock_.lock();
- auto it = fb_map_.begin();
+
int ret = 0;
+ FBKey key(num_planes, igem_handles);
- while (it != fb_map_.end()) {
- if (it->second.fb_id == fb) {
- it->second.fb_ref -= 1;
- if (it->second.fb_ref == 0) {
- ret = ReleaseFrameBuffer(it->first, fb, gpu_fd_, release_gem_handles);
- fb_map_.erase(it);
- }
- break;
+ auto it = fb_map_.find(key);
+ if (it != fb_map_.end()) {
+ it->second.fb_ref -= 1;
+ if (it->second.fb_ref == 0) {
+ ret = ReleaseFrameBuffer(it->first, it->second.fb_id, gpu_fd_);
+ fb_map_.erase(it);
}
- it++;
}
- if(it == fb_map_.end()) {
- ETRACE("RemoveFB not meet!");
+ if (it == fb_map_.end()) {
+ if (igem_handles[0] != 0 || igem_handles[1] != 0 || igem_handles[2] != 0 ||
+ igem_handles[3] != 0) {
+ ETRACE("Unable to find fb in cache. %d %d %d %d \n", igem_handles[0],
+ igem_handles[1], igem_handles[2], igem_handles[3]);
+ }
}
lock_.unlock();
auto it = fb_map_.begin();
while (it != fb_map_.end()) {
- ReleaseFrameBuffer(it->first, it->second.fb_id, gpu_fd_, false);
+ ReleaseFrameBuffer(it->first, it->second.fb_id, gpu_fd_);
}
lock_.unlock();
typedef struct {
uint32_t fb_id;
uint32_t fb_ref;
+ bool fb_created;
} FBValue;
struct FBHash {
class FrameBufferManager {
public:
- static FrameBufferManager *GetInstance(uint32_t gpu_fd);
+ static FrameBufferManager *GetInstance();
+ static void CreateInstance(uint32_t gpu_fd);
+ void RegisterGemHandles(const uint32_t &num_planes,
+ const uint32_t (&igem_handles)[4]);
uint32_t FindFB(const uint32_t &iwidth, const uint32_t &iheight,
const uint32_t &iframe_buffer_format,
const uint32_t &num_planes, const uint32_t (&igem_handles)[4],
const uint32_t (&ipitches)[4], const uint32_t (&ioffsets)[4]);
- int RemoveFB(const uint32_t &fb, bool release_gem_handles);
+ int RemoveFB(uint32_t num_planes, const uint32_t (&igem_handles)[4]);
private:
static FrameBufferManager *pInstance;
return true;
}
-bool Gralloc1BufferHandler::CanReleaseGemHandles(HWCNativeHandle handle) const {
- if (!handle) {
- return false;
- }
-
- if (handle->hwc_buffer_) {
- return true;
- }
-
- if (handle->imported_handle_) {
- return true;
- }
-
- return false;
-}
-
-bool Gralloc1BufferHandler::ReleaseBuffer(HWCNativeHandle handle,
- bool release_gem_handles) const {
+bool Gralloc1BufferHandler::ReleaseBuffer(HWCNativeHandle handle) const {
gralloc1_device_t *gralloc1_dvc =
reinterpret_cast<gralloc1_device_t *>(device_);
if (handle->hwc_buffer_) {
release_(gralloc1_dvc, handle->handle_);
} else if (handle->imported_handle_) {
- if (release_gem_handles) {
- uint32_t total_planes = handle->meta_data_.num_planes_;
- struct drm_gem_close gem_close;
- int last_gem_handle = -1;
-
- for (uint32_t plane = 0; plane < total_planes; plane++) {
- uint32_t current_gem_handle = handle->meta_data_.gem_handles_[plane];
- if ((last_gem_handle != -1) &&
- (current_gem_handle == static_cast<uint32_t>(last_gem_handle))) {
- break;
- }
-
- memset(&gem_close, 0, sizeof(gem_close));
- last_gem_handle = current_gem_handle;
- gem_close.handle = current_gem_handle;
-
- int ret = drmIoctl(fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
- if (ret) {
- ETRACE(
- "Failed to close gem handle ErrorCode: %d "
- "GemHandle: %d \n",
- ret, current_gem_handle);
- }
- }
- }
-
release_(gralloc1_dvc, handle->imported_handle_);
}
bool CreateBuffer(uint32_t w, uint32_t h, int format, HWCNativeHandle *handle,
uint32_t layer_type) const override;
- bool CanReleaseGemHandles(HWCNativeHandle handle) const;
- bool ReleaseBuffer(HWCNativeHandle handle,
- bool release_gem_handles = false) const override;
+ bool ReleaseBuffer(HWCNativeHandle handle) const override;
void DestroyHandle(HWCNativeHandle handle) const override;
bool ImportBuffer(HWCNativeHandle handle) const override;
void CopyHandle(HWCNativeHandle source,
}
#endif
-int ReleaseFrameBuffer(const FBKey& key, uint32_t fd, uint32_t gpu_fd,
- bool release_gem_handle) {
- int ret = drmModeRmFB(gpu_fd, fd);
+int ReleaseFrameBuffer(const FBKey &key, uint32_t fd, uint32_t gpu_fd) {
+ int ret = fd > 0 ? drmModeRmFB(gpu_fd, fd) : 0;
if (ret) {
ETRACE("Failed to Remove FD ErrorCode: %d FD: %d \n", ret, fd);
}
- if (!release_gem_handle) {
- return 0;
- }
-
uint32_t total_planes = key.num_planes_;
struct drm_gem_close gem_close;
int last_gem_handle = -1;
return true;
}
-bool GbmBufferHandler::CanReleaseGemHandles(HWCNativeHandle handle) const {
- return false;
-}
-
-bool GbmBufferHandler::ReleaseBuffer(HWCNativeHandle handle,
- bool /*release_gem_handles*/) const {
+bool GbmBufferHandler::ReleaseBuffer(HWCNativeHandle handle) const {
if (handle->bo || handle->imported_bo) {
if (handle->bo && handle->hwc_buffer_) {
gbm_bo_destroy(handle->bo);
bool CreateBuffer(uint32_t w, uint32_t h, int format, HWCNativeHandle *handle,
uint32_t layer_type) const override;
- bool CanReleaseGemHandles(HWCNativeHandle handle) const override;
- bool ReleaseBuffer(HWCNativeHandle handle,
- bool release_gem_handles = false) const override;
+ bool ReleaseBuffer(HWCNativeHandle handle) const override;
void DestroyHandle(HWCNativeHandle handle) const override;
void CopyHandle(HWCNativeHandle source,
HWCNativeHandle *target) const override;
}
#endif
-int ReleaseFrameBuffer(const FBKey& /*key*/, uint32_t fd, uint32_t gpu_fd,
- bool /*release_gem_handle*/) {
- return drmModeRmFB(gpu_fd, fd);
+int ReleaseFrameBuffer(const FBKey & /*key*/, uint32_t fd, uint32_t gpu_fd) {
+ return fd > 0 ? drmModeRmFB(gpu_fd, fd) : 0;
}
int CreateFrameBuffer(const uint32_t &iwidth, const uint32_t &iheight,
const uint32_t (&ioffsets)[4], uint32_t gpu_fd,
uint32_t *fb_id);
-int ReleaseFrameBuffer(const FBKey &key, uint32_t fd, uint32_t gpu_fd,
- bool release_gem_handle);
+int ReleaseFrameBuffer(const FBKey &key, uint32_t fd, uint32_t gpu_fd);
#endif // OS_LINUX_PLATFORMCOMMONDEFINES_H_
HWCNativeHandle *handle = NULL,
uint32_t layer_type = kLayerNormal) const = 0;
- virtual bool CanReleaseGemHandles(HWCNativeHandle handle) const = 0;
-
- virtual bool ReleaseBuffer(HWCNativeHandle handle,
- bool release_gem_handles = false) const = 0;
+ virtual bool ReleaseBuffer(HWCNativeHandle handle) const = 0;
virtual void DestroyHandle(HWCNativeHandle handle) const = 0;
} else {
frame_buffer_format_ = format_;
}
+
+ FrameBufferManager::GetInstance()->RegisterGemHandles(
+ image_.handle_->meta_data_.num_planes_,
+ image_.handle_->meta_data_.gem_handles_);
}
void DrmBuffer::InitializeFromNativeHandle(HWCNativeHandle handle,
image_.drm_fd_ = 0;
media_image_.drm_fd_ = 0;
- image_.drm_fd_ = FrameBufferManager::GetInstance(gpu_fd)->FindFB(
+ image_.drm_fd_ = FrameBufferManager::GetInstance()->FindFB(
width_, height_, frame_buffer_format_,
image_.handle_->meta_data_.num_planes_, gem_handles_, pitches_, offsets_);
media_image_.drm_fd_ = image_.drm_fd_;
#include <nativebufferhandler.h>
+#include "framebuffermanager.h"
+
namespace hwcomposer {
DrmDisplayManager::DrmDisplayManager(GpuDevice *device)
void DrmDisplayManager::InitializeDisplayResources() {
buffer_handler_.reset(NativeBufferHandler::CreateInstance(fd_));
+ // FIXME: Remove this once #303 is fixed.
+ FrameBufferManager::CreateInstance(fd_);
if (!buffer_handler_) {
ETRACE("Failed to create native buffer handler instance");
return;