compositor/va/varenderer.cpp \
core/gpudevice.cpp \
core/hwclayer.cpp \
+ core/hwclayerbuffermanager.cpp \
core/logicaldisplay.cpp \
core/logicaldisplaymanager.cpp \
core/mosaicdisplay.cpp \
compositor/nativesurface.cpp \
compositor/renderstate.cpp \
core/hwclayer.cpp \
+ core/hwclayerbuffermanager.cpp \
core/overlaylayer.cpp \
core/gpudevice.cpp \
core/logicaldisplay.cpp \
Compositor::~Compositor() {
}
-void Compositor::Init(DisplayPlaneManager *plane_manager) {
+void Compositor::Init(DisplayPlaneManager *plane_manager,
+ HwcLayerBufferManager *buffer_manager) {
if (!thread_)
thread_.reset(new CompositorThread());
- thread_->Initialize(plane_manager);
+ thread_->Initialize(plane_manager, buffer_manager);
}
void Compositor::EnsureTasksAreDone() {
class NativeBufferHandler;
class DisplayPlaneManager;
+class HwcLayerBufferManager;
struct OverlayLayer;
class Compositor {
Compositor();
~Compositor();
- void Init(DisplayPlaneManager *plane_manager);
+ void Init(DisplayPlaneManager *plane_manager,
+ HwcLayerBufferManager *buffer_manager);
void Reset();
Compositor(const Compositor &) = delete;
#include "hwcutils.h"
#include "hwctrace.h"
+#include "hwclayerbuffermanager.h"
#include "nativegpuresource.h"
#include "overlaylayer.h"
#include "renderer.h"
CompositorThread::~CompositorThread() {
}
-void CompositorThread::Initialize(DisplayPlaneManager *plane_manager) {
+void CompositorThread::Initialize(DisplayPlaneManager *plane_manager,
+ HwcLayerBufferManager *buffer_manager) {
tasks_lock_.lock();
if (!gpu_resource_handler_)
gpu_resource_handler_.reset(CreateNativeGpuResourceHandler());
plane_manager_ = plane_manager;
+ buffer_manager_ = buffer_manager;
tasks_lock_.unlock();
if (!InitWorker()) {
ETRACE("Failed to initalize CompositorThread. %s", PRINTERROR());
void CompositorThread::Ensure3DRenderer() {
if (!gl_renderer_) {
gl_renderer_.reset(Create3DRenderer());
- if (!gl_renderer_->Init()) {
+ if (!gl_renderer_->Init(buffer_manager_)) {
ETRACE("Failed to initialize OpenGL compositor %s", PRINTERROR());
gl_renderer_.reset(nullptr);
}
class OverlayBuffer;
class DisplayPlaneManager;
+class HwcLayerBufferManager;
class CompositorThread : public HWCThread {
public:
CompositorThread();
~CompositorThread() override;
- void Initialize(DisplayPlaneManager* plane_manager);
+ void Initialize(DisplayPlaneManager* plane_manager,
+ HwcLayerBufferManager* buffer_manager);
void Draw(std::vector<DrawState>& states,
std::vector<DrawState>& media_states,
bool disable_explicit_sync_;
bool release_all_resources_;
DisplayPlaneManager* plane_manager_ = NULL;
+ HwcLayerBufferManager* buffer_manager_ = NULL;
uint32_t tasks_ = kNone;
FDHandler fd_chandler_;
HWCEvent cevent_;
#include "nativesurface.h"
#include "renderstate.h"
#include "shim.h"
+#include "hwclayerbuffermanager.h"
namespace hwcomposer {
GLRenderer::~GLRenderer() {
+ if (!context_.MakeCurrent()) {
+ ETRACE("Failed make current context.");
+ return;
+ }
+
+ if (buffer_manager_)
+ buffer_manager_->PurgeGraphicsResources();
if (vertex_array_)
glDeleteVertexArraysOES(1, &vertex_array_);
}
-bool GLRenderer::Init() {
+bool GLRenderer::Init(HwcLayerBufferManager *buffer_manager) {
// clang-format off
+ buffer_manager_ = buffer_manager;
const GLfloat verts[] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f,
0.0f, 2.0f, 2.0f, 0.0f, 2.0f, 0.0f};
// clang-format on
GLRenderer() = default;
~GLRenderer();
- bool Init() override;
+ bool Init(HwcLayerBufferManager *buffer_manager) override;
bool Draw(const std::vector<RenderState> &commands, NativeSurface *surface,
bool clear_surface) override;
GLProgram *GetProgram(unsigned texture_count);
EGLOffScreenContext context_;
+ HwcLayerBufferManager *buffer_manager_;
std::vector<std::unique_ptr<GLProgram>> programs_;
GLuint vertex_array_ = 0;
glBindTexture(GL_TEXTURE_2D, 0);
tex_ = texture;
- eglDestroyImageKHR(egl_display, image);
// Create Fb.
GLuint gl_fb;
ETRACE("Failed to make import image.");
return false;
}
-
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
- (GLeglImageOES)egl_image);
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ GLuint texture = (GLuint)buffer->GetImageTexture();
layer_textures_.emplace_back(texture);
- eglDestroyImageKHR(egl_display, egl_image);
}
return true;
}
void NativeGLResource::Reset() {
- GLuint texture_id = 0;
- size_t size = layer_textures_.size();
- for (size_t i = 0; i < size; i++) {
- texture_id = layer_textures_.at(i);
- glDeleteTextures(1, &texture_id);
- }
}
GpuResourceHandle NativeGLResource::GetResourceHandle(
#define COMMON_COMPOSITOR_RENDERER_H_
#include <stdint.h>
+#include <stddef.h>
#include <vector>
class NativeSurface;
struct RenderState;
struct MediaState;
+class HwcLayerBufferManager;
class Renderer {
public:
Renderer& operator=(const Renderer& rhs) = delete;
// Needs to be implemented for 3D Renderer's only.
- virtual bool Init() {
+ virtual bool Init(HwcLayerBufferManager* /*buffer_manager*/) {
return false;
}
+
virtual bool Draw(const std::vector<RenderState>& /*commands*/,
NativeSurface* /*surface*/, bool /*clear_surface*/) {
return false;
--- /dev/null
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "hwclayerbuffermanager.h"
+
+namespace hwcomposer {
+
+HwcLayerBufferManager::HwcLayerBufferManager() {
+ for(size_t i = 0; i < BUFFER_CACHE_LENGTH; i++)
+ cached_buffers_.emplace_back();
+}
+
+HwcLayerBufferManager::~HwcLayerBufferManager() {
+ PurgeBuffer();
+}
+
+void HwcLayerBufferManager::PurgeBuffer() {
+ for(auto &map : cached_buffers_) {
+ map.clear();
+ }
+}
+
+void HwcLayerBufferManager::PurgeGraphicsResources() {
+ for (auto& map : cached_buffers_) {
+ for (auto& pair : map) {
+ pair.second->DeleteImage();
+ pair.second->DeleteTexture();
+ }
+ }
+}
+
+void HwcLayerBufferManager::Dump() {
+}
+
+std::shared_ptr<OverlayBuffer>& HwcLayerBufferManager::FindCachedBuffer(const HWCNativeBuffer& native_buffer) {
+
+ BUFFER_MAP& first_map = cached_buffers_[0];
+ static std::shared_ptr<OverlayBuffer> pBufNull = nullptr;
+ for (auto& map : cached_buffers_) {
+ if (map.count(native_buffer)) {
+ std::shared_ptr<OverlayBuffer>& pBuf = map[native_buffer];
+ if (&map != &first_map) {
+ first_map.emplace(std::make_pair(native_buffer, pBuf));
+ map.erase(native_buffer);
+ }
+#ifdef CACHE_TRACING
+ hit_count_++;
+#endif
+ return pBuf;
+ }
+ }
+
+#ifdef CACHE_TRACING
+ miss_count_++;
+ if (miss_count_ % 100 == 0)
+ ICACHETRACE("cache miss count is %llu, while hit count is %llu",
+ miss_count_, hit_count_);
+#endif
+
+ return pBufNull;
+}
+
+void HwcLayerBufferManager::RegisterBuffer(const HWCNativeBuffer& native_buffer, std::shared_ptr<OverlayBuffer>& pBuffer) {
+
+ BUFFER_MAP& first_map = cached_buffers_[0];
+ first_map.emplace(std::make_pair(native_buffer, pBuffer));
+}
+
+void HwcLayerBufferManager::RefreshBufferCache() {
+ auto begin = cached_buffers_.begin();
+ cached_buffers_.emplace(begin);
+ cached_buffers_.pop_back();
+}
+
+} // namespace hwcomposer
--- /dev/null
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+/*
+Design of hwclayerbuffermanager:
+The purpose is to add cache magagement to external buffer owned by hwcLayer
+to avoid import buffer and glimage/texture generation overhead
+
+1: the hwclayerbuffermanager is owned per display, as each display has a
+separate
+GL context
+2: hwclayerbuffermanager stores a refernce of external buffers in a vector
+ cached_buffers, each vector member is hash map.
+ The vector stores history buffer in this way, vector[0] is for the current
+ frame buffers, vector[1] is for last frame (-1) buffers, vector[2] is -2
+ frames buffers etc. A constant (currently 4) frames of buffers is stored.
+ When a buffer refernce is stored in vector[3] and it is not used in the
+ current frame present, it will go out of scope and be released.
+ If a buffer is fetched from map, it will always re-registered in vector[0]
+map.
+3. By this way, drm_buffer now owns eglImage and gltexture and they
+ can be resued.
+*/
+
+#ifndef COMMON_CORE_HWCLAYERBUFFER_MANAGER_H_
+#define COMMON_CORE_HWCLAYERBUFFER_MANAGER_H_
+
+#include <hwcdefs.h>
+#include <platformdefines.h>
+#include <hwctrace.h>
+
+#include <memory>
+#include <unordered_map>
+
+#include "overlaybuffer.h"
+
+namespace hwcomposer {
+
+struct HwcLayer;
+class OverlayBuffer;
+class NativeBufferHandler;
+
+class HwcLayerBufferManager {
+
+public:
+ HwcLayerBufferManager();
+ ~HwcLayerBufferManager();
+ void Dump();
+ std::shared_ptr<OverlayBuffer>& FindCachedBuffer(const HWCNativeBuffer& native_buffer);
+ void RegisterBuffer(const HWCNativeBuffer& native_buffer, std::shared_ptr<OverlayBuffer>& pBuffer);
+ void RefreshBufferCache();
+ void PurgeGraphicsResources();
+
+private:
+ void PurgeBuffer();
+
+#define BUFFER_CACHE_LENGTH 4
+ typedef std::unordered_map<HWCNativeBuffer, std::shared_ptr<OverlayBuffer>,
+ BufferHash, BufferEqual> BUFFER_MAP;
+ std::vector<BUFFER_MAP> cached_buffers_;
+};
+
+} // namespace hwcomposer
+#endif // COMMON_CORE_OVERLAYLAYER_H_
#include "hwcutils.h"
#include <nativebufferhandler.h>
+#include "hwclayerbuffermanager.h"
namespace hwcomposer {
}
}
-OverlayLayer::ImportedBuffer::ImportedBuffer(OverlayBuffer* buffer,
- int32_t acquire_fence)
+OverlayLayer::ImportedBuffer::ImportedBuffer(
+ std::shared_ptr<OverlayBuffer>& buffer, int32_t acquire_fence)
: acquire_fence_(acquire_fence) {
- buffer_.reset(buffer);
+ buffer_ = buffer;
}
void OverlayLayer::SetAcquireFence(int32_t acquire_fence) {
}
OverlayBuffer* OverlayLayer::GetBuffer() const {
+ if (imported_buffer_->buffer_.get() == NULL)
+ ETRACE("hwc layer get NullBuffer");
return imported_buffer_->buffer_.get();
}
void OverlayLayer::SetBuffer(NativeBufferHandler* buffer_handler,
- HWCNativeHandle handle, int32_t acquire_fence) {
- OverlayBuffer* buffer = OverlayBuffer::CreateOverlayBuffer();
- buffer->InitializeFromNativeHandle(handle, buffer_handler);
+ HWCNativeHandle handle, int32_t acquire_fence,
+ HwcLayerBufferManager* buffer_manager) {
+ std::shared_ptr<OverlayBuffer> buffer(NULL);
+
+ if (buffer_manager) {
+ buffer = buffer_manager->FindCachedBuffer(GETNATIVEBUFFER(handle));
+ }
+
+ if (buffer == NULL) {
+ buffer = OverlayBuffer::CreateOverlayBuffer();
+ buffer->InitializeFromNativeHandle(handle, buffer_handler);
+ if (buffer_manager) {
+ buffer_manager->RegisterBuffer(GETNATIVEBUFFER(handle), buffer);
+ }
+ }
imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence));
}
void OverlayLayer::InitializeState(HwcLayer* layer,
NativeBufferHandler* buffer_handler,
+ HwcLayerBufferManager* buffer_manager,
OverlayLayer* previous_layer,
uint32_t z_order, uint32_t layer_index,
uint32_t max_height, HWCRotation rotation,
source_crop_height_ = layer->GetSourceCropHeight();
source_crop_ = layer->GetSourceCrop();
blending_ = layer->GetBlending();
- SetBuffer(buffer_handler, layer->GetNativeHandle(), layer->GetAcquireFence());
+ SetBuffer(buffer_handler, layer->GetNativeHandle(), layer->GetAcquireFence(),
+ buffer_manager);
ValidateForOverlayUsage();
if (previous_layer) {
ValidatePreviousFrameState(previous_layer, layer);
void OverlayLayer::InitializeFromHwcLayer(
HwcLayer* layer, NativeBufferHandler* buffer_handler,
- OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
- uint32_t max_height, HWCRotation rotation, bool handle_constraints) {
+ HwcLayerBufferManager* buffer_manager, OverlayLayer* previous_layer,
+ uint32_t z_order, uint32_t layer_index, uint32_t max_height,
+ HWCRotation rotation, bool handle_constraints) {
display_frame_width_ = layer->GetDisplayFrameWidth();
display_frame_height_ = layer->GetDisplayFrameHeight();
display_frame_ = layer->GetDisplayFrame();
- InitializeState(layer, buffer_handler, previous_layer, z_order, layer_index,
- max_height, rotation, handle_constraints);
+ InitializeState(layer, buffer_handler, buffer_manager, previous_layer,
+ z_order, layer_index, max_height, rotation,
+ handle_constraints);
}
void OverlayLayer::InitializeFromScaledHwcLayer(
HwcLayer* layer, NativeBufferHandler* buffer_handler,
- OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
- const HwcRect<int>& display_frame, uint32_t max_height,
- HWCRotation rotation, bool handle_constraints) {
+ HwcLayerBufferManager* buffer_manager, OverlayLayer* previous_layer,
+ uint32_t z_order, uint32_t layer_index, const HwcRect<int>& display_frame,
+ uint32_t max_height, HWCRotation rotation, bool handle_constraints) {
SetDisplayFrame(display_frame);
- InitializeState(layer, buffer_handler, previous_layer, z_order, layer_index,
- max_height, rotation, handle_constraints);
+ InitializeState(layer, buffer_handler, buffer_manager, previous_layer,
+ z_order, layer_index, max_height, rotation,
+ handle_constraints);
}
void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
}
void OverlayLayer::ValidateForOverlayUsage() {
- const std::unique_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
+ const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
if (buffer->GetUsage() & kLayerCursor) {
type_ = kLayerCursor;
} else if (buffer->IsVideoBuffer()) {
struct HwcLayer;
class OverlayBuffer;
class NativeBufferHandler;
+class HwcLayerBufferManager;
struct OverlayLayer {
OverlayLayer() = default;
// Initialize OverlayLayer from layer.
void InitializeFromHwcLayer(HwcLayer* layer,
NativeBufferHandler* buffer_handler,
+ HwcLayerBufferManager* buffer_manager,
OverlayLayer* previous_layer, uint32_t z_order,
uint32_t layer_index, uint32_t max_height,
HWCRotation rotation, bool handle_constraints);
- void InitializeFromScaledHwcLayer(HwcLayer* layer,
- NativeBufferHandler* buffer_handler,
- OverlayLayer* previous_layer,
- uint32_t z_order, uint32_t layer_index,
- const HwcRect<int>& display_frame,
- uint32_t max_height, HWCRotation rotation,
- bool handle_constraints);
+ void InitializeFromScaledHwcLayer(
+ HwcLayer* layer, NativeBufferHandler* buffer_handler,
+ HwcLayerBufferManager* buffer_manager, OverlayLayer* previous_layer,
+ uint32_t z_order, uint32_t layer_index, const HwcRect<int>& display_frame,
+ uint32_t max_height, HWCRotation rotation, bool handle_constraints);
// Get z order of this layer.
uint32_t GetZorder() const {
return z_order_;
OverlayBuffer* GetBuffer() const;
void SetBuffer(NativeBufferHandler* buffer_handler, HWCNativeHandle handle,
- int32_t acquire_fence);
+ int32_t acquire_fence,
+ HwcLayerBufferManager* buffer_manager = NULL);
void ResetBuffer();
void SetSourceCrop(const HwcRect<float>& source_crop);
struct ImportedBuffer {
public:
- ImportedBuffer(OverlayBuffer* buffer, int32_t acquire_fence);
+ ImportedBuffer(std::shared_ptr<OverlayBuffer>& buffer,
+ int32_t acquire_fence);
~ImportedBuffer();
- std::unique_ptr<OverlayBuffer> buffer_;
+ std::shared_ptr<OverlayBuffer> buffer_;
int32_t acquire_fence_ = -1;
};
void UpdateSurfaceDamage(HwcLayer* layer);
void InitializeState(HwcLayer* layer, NativeBufferHandler* buffer_handler,
+ HwcLayerBufferManager* buffer_manager,
OverlayLayer* previous_layer, uint32_t z_order,
uint32_t layer_index, uint32_t max_height,
HWCRotation rotation, bool handle_constraints);
return false;
}
+ buffer_manager_.reset(new HwcLayerBufferManager());
+ if (!buffer_manager_) {
+ ETRACE("Failed to construct hwc layer buffer manager");
+ return false;
+ }
+
vblank_handler_->SetPowerMode(kOff);
vblank_handler_->Init(gpu_fd_, pipe);
return true;
vblank_handler_->SetPowerMode(kOn);
power_mode_lock_.lock();
state_ &= ~kIgnoreIdleRefresh;
- compositor_.Init(display_plane_manager_.get());
+ compositor_.Init(display_plane_manager_.get(), buffer_manager_.get());
power_mode_lock_.unlock();
break;
default:
cursor_state_changed = true;
}
+ buffer_manager_->RefreshBufferCache();
+
for (size_t layer_index = 0; layer_index < size; layer_index++) {
HwcLayer* layer = source_layers.at(layer_index);
layer->SetReleaseFence(-1);
(display_frame.bottom * scaling_tracker_.scaling_height);
overlay_layer->InitializeFromScaledHwcLayer(
- layer, buffer_handler_, previous_layer, z_order, layer_index,
- display_frame, display_plane_manager_->GetHeight(), rotation_,
- handle_constraints);
+ layer, buffer_handler_, buffer_manager_.get(), previous_layer,
+ z_order, layer_index, display_frame,
+ display_plane_manager_->GetHeight(), rotation_, handle_constraints);
} else {
overlay_layer->InitializeFromHwcLayer(
- layer, buffer_handler_, previous_layer, z_order, layer_index,
- display_plane_manager_->GetHeight(), rotation_, handle_constraints);
+ layer, buffer_handler_, buffer_manager_.get(), previous_layer,
+ z_order, layer_index, display_plane_manager_->GetHeight(), rotation_,
+ handle_constraints);
}
if (!overlay_layer->IsVisible()) {
#include "hwcthread.h"
#include "vblankeventhandler.h"
#include "platformdefines.h"
+#include "hwclayerbuffermanager.h"
namespace hwcomposer {
struct gamma_colors {
struct gamma_colors gamma_;
std::unique_ptr<VblankEventHandler> vblank_handler_;
std::unique_ptr<DisplayPlaneManager> display_plane_manager_;
+ std::unique_ptr<HwcLayerBufferManager> buffer_manager_;
std::vector<OverlayLayer> in_flight_layers_;
DisplayPlaneStateList previous_plane_state_;
NativeBufferHandler* buffer_handler_;
buffer_handler_(buffer_handler),
width_(0),
height_(0) {
+ buffer_manager_.reset(new HwcLayerBufferManager());
+ if (!buffer_manager_) {
+ ETRACE("Failed to construct hwc layer buffer manager");
+ }
}
VirtualDisplay::~VirtualDisplay() {
}
void VirtualDisplay::InitVirtualDisplay(uint32_t width, uint32_t height) {
- compositor_.Init(nullptr);
+ compositor_.Init(nullptr, buffer_manager_.get());
width_ = width;
height_ = height;
}
*retire_fence = -1;
uint32_t z_order = 0;
+ buffer_manager_->RefreshBufferCache();
for (size_t layer_index = 0; layer_index < size; layer_index++) {
- HwcLayer* layer = source_layers.at(layer_index);
+ HwcLayer *layer = source_layers.at(layer_index);
layer->SetReleaseFence(-1);
if (!layer->IsVisible())
continue;
previous_layer = &(in_flight_layers_.at(z_order));
}
- overlay_layer.InitializeFromHwcLayer(layer, buffer_handler_, previous_layer,
- z_order, layer_index, width_,
- kRotateNone, handle_constraints);
+ overlay_layer.InitializeFromHwcLayer(
+ layer, buffer_handler_, buffer_manager_.get(), previous_layer, z_order,
+ layer_index, width_, kRotateNone, handle_constraints);
index.emplace_back(z_order);
layers_rects.emplace_back(layer->GetDisplayFrame());
z_order++;
#include <vector>
#include "compositor.h"
+#include "hwclayerbuffermanager.h"
namespace hwcomposer {
struct HwcLayer;
uint32_t height_ = 1;
std::vector<OverlayLayer> in_flight_layers_;
HWCNativeHandle handle_ = 0;
+ std::unique_ptr<HwcLayerBufferManager> buffer_manager_;
};
} // namespace hwcomposer
#define ICOMPOSITORTRACE(fmt, ...) ((void)0)
#endif
+#ifdef CACHE_TRACING
+#define ICACHETRACE ITRACE
+#else
+#define ICACHETRACE ((void)0)
+#endif
+
// Errors
#define PRINTERROR() strerror(-errno)
#include <cutils/log.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
-
#include <ui/GraphicBuffer.h>
-
#include "platformcommondefines.h"
-
+#include <cros_gralloc_handle.h>
#define DRV_I915 1
#include <i915_private_android_types.h>
};
typedef struct gralloc_handle* HWCNativeHandle;
+typedef struct cros_gralloc_handle HWCNativeBuffer;
+#define GETNATIVEBUFFER(handle) (*(cros_gralloc_handle*)(handle->handle_))
+
+
+struct BufferHash {
+ size_t operator()(HWCNativeBuffer const& buffer) const {
+ const native_handle_t & p = buffer.base;
+ std::size_t seed = 0;
+ for (int i = 0; i < p.numFds + p.numInts; i++) {
+ hash_combine_hwc(seed, (const size_t)p.data[i]);
+ }
+ return seed;
+ }
+};
+
+struct BufferEqual {
+ bool operator()(const HWCNativeBuffer& buffer1, const HWCNativeBuffer& buffer2) const {
+ const native_handle_t &p1 = buffer1.base;
+ const native_handle_t &p2 = buffer2.base;
+ bool equal = (p1.numFds == p2.numFds) && (p1.numInts == p2.numInts);
+ if (equal) {
+ for (int i = 0; i < p1.numFds + p1.numInts; i++) {
+ equal = equal && (p1.data[i] == p2.data[i]);
+ if (!equal)
+ break;
+ }
+ }
+ return equal;
+ }
+};
+
#define VTRACE(fmt, ...) ALOGV("%s: " fmt, __func__, ##__VA_ARGS__)
#define DTRACE(fmt, ...) ALOGD("%s: " fmt, __func__, ##__VA_ARGS__)
};
typedef struct gbm_handle* HWCNativeHandle;
+#define GETNATIVEBUFFER(handle) (handle->import_data)
+
+#ifdef USE_MINIGBM
+typedef gbm_import_fd_planar_data HWCNativeBuffer;
+struct BufferHash {
+ size_t operator()(gbm_import_fd_planar_data const& p) const {
+ std::size_t seed = 0;
+ for (int i = 0; i < GBM_MAX_PLANES; i++) {
+ hash_combine_hwc(seed, (const size_t)p.fds[i]);
+ }
+ // avoid to consider next information?
+ hash_combine_hwc(seed, p.width);
+ hash_combine_hwc(seed, p.height);
+ hash_combine_hwc(seed, p.format);
+ return seed;
+ }
+};
+
+struct BufferEqual {
+ bool operator()(const gbm_import_fd_planar_data& p1,
+ const gbm_import_fd_planar_data& p2) const {
+ bool equal = true;
+ for (int i = 0; i < GBM_MAX_PLANES; i++) {
+ equal = equal && (p1.fds[i] == p2.fds[i]);
+ if (!equal)
+ break;
+ }
+ if (equal)
+ equal = equal && (p1.width == p2.width) && (p1.height == p2.height) &&
+ (p1.format == p2.format);
+ return equal;
+ }
+};
+#else
+
+typedef gbm_import_fd_data HWCNativeBuffer;
+struct BufferHash {
+ size_t operator()(gbm_import_fd_data const& p) const {
+ std::size_t seed = 0;
+ hash_combine_hwc(seed, p.fd);
+ hash_combine_hwc(seed, p.width);
+ hash_combine_hwc(seed, p.height);
+ hash_combine_hwc(seed, p.stride);
+ hash_combine_hwc(seed, p.format);
+ return seed;
+ }
+};
+struct BufferEqual {
+ bool operator()(const gbm_import_fd_data& p1,
+ const gbm_import_fd_data& p2) const {
+ bool equal = (p1.fd == p2.fd) && (p1.width == p2.width) &&
+ (p1.height == p2.height) && (p1.stride == p2.stride) &&
+ (p1.format == p2.format);
+ return equal;
+ }
+};
+
+#endif
#ifdef _cplusplus
extern "C" {
// minigbm specific DRM_FORMAT_YVU420_ANDROID enum
#define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7')
+inline void hash_combine_hwc(size_t seed, size_t value) {
+ seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+}
+
#endif // OS_LINUX_PLATFORMCOMMONDEFINES_H_
DrmBuffer::~DrmBuffer() {
ReleaseFrameBuffer();
+#if USE_GL
+ if (image_)
+ eglDestroyImageKHR(display_, image_);
+ if (texture_) {
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ glDeleteTextures(1, &texture_);
+ }
+#elif USE_VK
+
+#endif
if (buffer_handler_ && handle_) {
buffer_handler_->ReleaseBuffer(handle_);
}
GpuImage DrmBuffer::ImportImage(GpuDisplay egl_display) {
+ if (image_)
+ return image_;
+
#ifdef USE_GL
EGLImageKHR image = EGL_NO_IMAGE_KHR;
// Note: If eglCreateImageKHR is successful for a EGL_LINUX_DMA_BUF_EXT
static_cast<EGLClientBuffer>(nullptr), attr_list);
}
+ image_ = image;
+ display_ = egl_display;
return image;
#elif USE_VK
struct vk_import import;
import.res = vkCreateDmaBufImageINTEL(egl_display, &image_create, NULL,
&import.memory, &import.image);
+ image_ = import;
+ display_ = egl_display;
return import;
#else
return NULL;
#endif
}
+void DrmBuffer::DeleteImage() {
+#if USE_GL
+ if (image_)
+ eglDestroyImageKHR(display_, image_);
+ image_ = 0;
+#endif
+}
+
+void DrmBuffer::DeleteTexture() {
+#if USE_GL
+ if (texture_) {
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ glDeleteTextures(1, &texture_);
+ }
+#endif
+}
+
+uint32_t DrmBuffer::GetImageTexture() {
+#ifdef USE_GL
+ if (texture_ != 0) {
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
+ (GLeglImageOES)image_);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ return texture_;
+ }
+
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image_);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
+ texture_ = texture;
+ return texture;
+#elif USE_VK
+ return 0;
+#else
+ return 0;
+#endif
+}
+
void DrmBuffer::SetRecommendedFormat(uint32_t format) {
frame_buffer_format_ = format;
}
bool DrmBuffer::CreateFrameBuffer(uint32_t gpu_fd) {
- ReleaseFrameBuffer();
+ if (fb_id_) {
+ // Has been created before
+ return true;
+ }
+
int ret = drmModeAddFB2(gpu_fd, width_, height_, frame_buffer_format_,
gem_handles_, pitches_, offsets_, &fb_id_, 0);
DUMPTRACE("DrmBuffer Information Ends. -------------");
}
-OverlayBuffer* OverlayBuffer::CreateOverlayBuffer() {
- return new DrmBuffer();
+std::shared_ptr<OverlayBuffer> OverlayBuffer::CreateOverlayBuffer() {
+ return std::make_shared<DrmBuffer>();
}
} // namespace hwcomposer
}
GpuImage ImportImage(GpuDisplay egl_display) override;
+ void DeleteImage() override;
+
+ uint32_t GetImageTexture() override;
+ void DeleteTexture() override;
bool CreateFrameBuffer(uint32_t gpu_fd) override;
bool is_yuv_ = false;
HWCNativeHandle handle_ = 0;
NativeBufferHandler* buffer_handler_ = 0;
+ GpuImage image_ = 0;
+ GpuDisplay display_ = 0;
+ uint32_t texture_ = 0;
};
} // namespace hwcomposer
#include <platformdefines.h>
+#include <memory>
+
#include "compositordefs.h"
namespace hwcomposer {
class OverlayBuffer {
public:
- static OverlayBuffer* CreateOverlayBuffer();
+ static std::shared_ptr<OverlayBuffer> CreateOverlayBuffer();
OverlayBuffer(OverlayBuffer&& rhs) = default;
OverlayBuffer& operator=(OverlayBuffer&& other) = default;
virtual const uint32_t* GetOffsets() const = 0;
virtual GpuImage ImportImage(GpuDisplay egl_display) = 0;
+ virtual void DeleteImage() = 0;
+
+ virtual uint32_t GetImageTexture() = 0;
+ virtual void DeleteTexture() = 0;
virtual bool CreateFrameBuffer(uint32_t gpu_fd) = 0;