common/core/gpudevice.cpp \
common/core/nativesync.cpp \
common/core/overlaybuffer.cpp \
+ common/core/overlaybuffermanager.cpp \
common/core/overlaylayer.cpp \
common/display/display.cpp \
common/display/displayplane.cpp \
common/core/hwclayer.cpp \
common/core/nativesync.cpp \
common/core/overlaybuffer.cpp \
+ common/core/overlaybuffermanager.cpp \
common/core/overlaylayer.cpp \
common/display/display.cpp \
common/display/displayqueue.cpp \
bool Compositor::DrawOffscreen(std::vector<OverlayLayer> &layers,
const std::vector<HwcRect<int>> &display_frame,
const std::vector<size_t> &source_layers,
- NativeBufferHandler *buffer_handler,
+ OverlayBufferManager *buffer_manager,
uint32_t width, uint32_t height,
HWCNativeHandle output_handle,
int32_t *retire_fence) {
}
std::unique_ptr<NativeSurface> surface(CreateBackBuffer(width, height));
- surface->InitializeForOffScreenRendering(buffer_handler, output_handle);
+ surface->InitializeForOffScreenRendering(buffer_manager, output_handle);
if (!Render(layers, surface.get(), comp_regions))
return false;
namespace hwcomposer {
-class NativeBufferHandler;
+class OverlayBufferManager;
struct OverlayLayer;
class Compositor {
bool DrawOffscreen(std::vector<OverlayLayer> &layers,
const std::vector<HwcRect<int>> &display_frame,
const std::vector<size_t> &source_layers,
- NativeBufferHandler *buffer_handler, uint32_t width,
+ OverlayBufferManager *buffer_manager, uint32_t width,
uint32_t height, HWCNativeHandle output_handle,
int32_t *retire_fence);
void InsertFence(uint64_t fence);
#include "displayplane.h"
#include "hwctrace.h"
#include "nativebufferhandler.h"
+#include "overlaybuffermanager.h"
namespace hwcomposer {
}
}
-bool NativeSurface::Init(NativeBufferHandler *buffer_handler) {
- buffer_handler_ = buffer_handler;
+bool NativeSurface::Init(OverlayBufferManager *buffer_manager) {
+ buffer_handler_ = buffer_manager->GetNativeBufferHandler();
buffer_handler_->CreateBuffer(width_, height_, 0, &native_handle_);
if (!native_handle_) {
ETRACE("Failed to create buffer.");
}
ref_count_ = 0;
- InitializeLayer(buffer_handler_, native_handle_);
+ InitializeLayer(buffer_manager, native_handle_);
return true;
}
bool NativeSurface::InitializeForOffScreenRendering(
- NativeBufferHandler *buffer_handler, HWCNativeHandle native_handle) {
- InitializeLayer(buffer_handler, native_handle);
+ OverlayBufferManager *buffer_manager, HWCNativeHandle native_handle) {
+ InitializeLayer(buffer_manager, native_handle);
layer_.SetSourceCrop(HwcRect<float>(0, 0, width_, height_));
layer_.SetDisplayFrame(HwcRect<int>(0, 0, width_, height_));
layer_.GetBuffer()->CreateFrameBuffer(gpu_fd);
}
-void NativeSurface::InitializeLayer(NativeBufferHandler *buffer_handler,
+void NativeSurface::InitializeLayer(OverlayBufferManager *buffer_manager,
HWCNativeHandle native_handle) {
- OverlayBuffer *overlay_buffer = new OverlayBuffer();
- overlay_buffer->InitializeFromNativeHandle(native_handle, buffer_handler);
+ ImportedBuffer *buffer =
+ buffer_manager->CreateBufferFromNativeHandle(native_handle);
+ OverlayBuffer *overlay_buffer = buffer->buffer_;
width_ = overlay_buffer->GetWidth();
height_ = overlay_buffer->GetHeight();
layer_.SetNativeHandle(native_handle_);
layer_.SetBlending(HWCBlending::kBlendingPremult);
layer_.SetTransform(0);
- layer_.SetBuffer(overlay_buffer);
+ layer_.SetBuffer(buffer);
}
void NativeSurface::ResetInFlightMode() {
namespace hwcomposer {
class NativeBufferHandler;
+class OverlayBufferManager;
class NativeSurface {
public:
virtual ~NativeSurface();
- bool Init(NativeBufferHandler* buffer_handler);
+ bool Init(OverlayBufferManager* buffer_manager);
- bool InitializeForOffScreenRendering(NativeBufferHandler* buffer_handler,
+ bool InitializeForOffScreenRendering(OverlayBufferManager* buffer_manager,
HWCNativeHandle native_handle);
virtual bool MakeCurrent() = 0;
OverlayLayer layer_;
private:
- void InitializeLayer(NativeBufferHandler* buffer_handler,
+ void InitializeLayer(OverlayBufferManager* buffer_manager,
HWCNativeHandle native_handle);
HWCNativeHandle native_handle_;
NativeBufferHandler* buffer_handler_;
namespace hwcomposer {
-class NativeBufferHandler;
class OverlayBuffer;
class VKSurface : public NativeSurface {
#include "drmscopedtypes.h"
#include "headless.h"
#include "hwcthread.h"
+#include "overlaybuffermanager.h"
#include "spinlock.h"
#include "vblankeventhandler.h"
#include "virtualdisplay.h"
private:
void HotPlugEventHandler();
- std::unique_ptr<NativeBufferHandler> buffer_handler_;
std::unique_ptr<NativeDisplay> headless_;
std::unique_ptr<NativeDisplay> virtual_display_;
std::vector<std::unique_ptr<NativeDisplay>> displays_;
std::vector<NativeDisplay *> connected_displays_;
std::shared_ptr<DisplayHotPlugEventCallback> callback_ = NULL;
+ std::unique_ptr<OverlayBufferManager> buffer_manager_;
int fd_ = -1;
ScopedFd hotplug_fd_;
SpinLock spin_lock_;
return false;
}
- ScopedDrmResourcesPtr res(drmModeGetResources(fd_));
- buffer_handler_.reset(NativeBufferHandler::CreateInstance(fd_));
- if (!buffer_handler_) {
- ETRACE("Failed to create native buffer handler instance");
+ buffer_manager_.reset(new OverlayBufferManager());
+ if (!buffer_manager_->Initialize(fd_)) {
+ ETRACE("Failed to Initialize Buffer Manager.");
return false;
}
+ ScopedDrmResourcesPtr res(drmModeGetResources(fd_));
+
for (int32_t i = 0; i < res->count_crtcs; ++i) {
ScopedDrmCrtcPtr c(drmModeGetCrtc(fd_, res->crtcs[i]));
if (!c) {
}
std::unique_ptr<NativeDisplay> display(new Display(fd_, i, c->crtc_id));
- if (!display->Initialize()) {
+ if (!display->Initialize(buffer_manager_.get())) {
ETRACE("Failed to Initialize Display %d", c->crtc_id);
return false;
}
displays_.emplace_back(std::move(display));
}
- virtual_display_.reset(new VirtualDisplay(fd_, buffer_handler_.get(), 0, 0));
+ virtual_display_.reset(new VirtualDisplay(fd_, buffer_manager_.get(), 0, 0));
if (!UpdateDisplayState()) {
ETRACE("Failed to connect display.");
}
fd_handler_.AddFd(hotplug_fd_.get());
+
if (!InitWorker()) {
ETRACE("Failed to initalizer thread to monitor Hot Plug events. %s",
PRINTERROR());
if (encoder && encoder->crtc_id) {
for (auto &display : displays_) {
if (encoder->crtc_id == display->CrtcId() &&
- display->Connect(mode, connector.get(), buffer_handler_.get())) {
+ display->Connect(mode, connector.get())) {
connected_displays_.emplace_back(display.get());
break;
}
for (auto &display : displays_) {
if (!display->IsConnected() &&
(encoder->possible_crtcs & (1 << display->Pipe())) &&
- display->Connect(mode, connector.get(), buffer_handler_.get())) {
+ display->Connect(mode, connector.get())) {
IHOTPLUGEVENTTRACE("connected pipe:%d \n", display->Pipe());
connected_displays_.emplace_back(display.get());
found_encoder = true;
return true;
}
-void NativeSync::SetState(State fence_state) {
- state_ = fence_state;
-}
-
int NativeSync::CreateNextTimelineFence() {
++timeline_;
return sw_sync_fence_create(timeline_fd_.get(), "NativeSync", timeline_);
// kReady: Fence can be signalled immediately. This is usually
// the case when we need to fallback to 3D Composition for
// a given buffer.
- // kIgnore: Dont signal the fence yet. This is the case when layer
- // associated with the fence is recycled.
// kSignalOnPageFlipEvent: Release the fence when we recieve PageFlipEvent
// notification.
- enum class State : int32_t { kReady, kIgnore, kSignalOnPageFlipEvent };
+ enum class State : int32_t { kReady, kSignalOnPageFlipEvent };
NativeSync();
virtual ~NativeSync();
int CreateNextTimelineFence();
- void SetState(State fence_state);
- State GetState() const {
- return state_;
- }
-
private:
int IncreaseTimelineToPoint(int point);
#ifndef USE_ANDROID_SYNC
ScopedFd timeline_fd_;
int64_t timeline_ = 0;
int64_t timeline_current_ = 0;
- State state_ = State::kSignalOnPageFlipEvent;
};
} // namespace hwcomposer
class OverlayBuffer {
public:
- OverlayBuffer() = default;
OverlayBuffer(OverlayBuffer&& rhs) = default;
OverlayBuffer& operator=(OverlayBuffer&& other) = default;
void Dump();
+ protected:
+ OverlayBuffer() = default;
+ friend class OverlayBufferManager;
+
private:
uint32_t width_ = 0;
uint32_t height_ = 0;
--- /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.
+*/
+
+#include "overlaybuffermanager.h"
+
+#include "hwctrace.h"
+#include "overlaylayer.h"
+
+namespace hwcomposer {
+
+ImportedBuffer::~ImportedBuffer() {
+ if (buffer_)
+ buffer_manager_->UnRegisterBuffer(buffer_);
+}
+
+OverlayBufferManager::~OverlayBufferManager() {
+}
+
+bool OverlayBufferManager::Initialize(uint32_t gpu_fd) {
+ buffer_handler_.reset(NativeBufferHandler::CreateInstance(gpu_fd));
+ if (!buffer_handler_) {
+ ETRACE("Failed to create native buffer handler instance");
+ return false;
+ }
+
+ return true;
+}
+
+ImportedBuffer* OverlayBufferManager::CreateBuffer(const HwcBuffer& bo) {
+ ScopedSpinLock lock(spin_lock_);
+ buffers_.emplace_back();
+ Buffer& buffer = buffers_.back();
+ buffer.buffer_.reset(new OverlayBuffer());
+ buffer.buffer_->Initialize(bo);
+ buffer.ref_count_ = 1;
+ buffer.sync_object_.reset(new NativeSync());
+ if (!buffer.sync_object_->Init()) {
+ ETRACE("Failed to create sync object.");
+ }
+
+ return new ImportedBuffer(buffer.buffer_.get(), this,
+ buffer.sync_object_->CreateNextTimelineFence());
+}
+
+ImportedBuffer* OverlayBufferManager::CreateBufferFromNativeHandle(
+ HWCNativeHandle handle) {
+ ScopedSpinLock lock(spin_lock_);
+ buffers_.emplace_back();
+ Buffer& buffer = buffers_.back();
+ buffer.buffer_.reset(new OverlayBuffer());
+ buffer.buffer_->InitializeFromNativeHandle(handle, buffer_handler_.get());
+ buffer.ref_count_ = 1;
+ buffer.sync_object_.reset(new NativeSync());
+ if (!buffer.sync_object_->Init()) {
+ ETRACE("Failed to create sync object.");
+ }
+
+ return new ImportedBuffer(buffer.buffer_.get(), this,
+ buffer.sync_object_->CreateNextTimelineFence());
+}
+
+void OverlayBufferManager::RegisterBuffer(OverlayBuffer* buffer) {
+ ScopedSpinLock lock(spin_lock_);
+ for (Buffer& overlay_buffer : buffers_) {
+ if (overlay_buffer.buffer_.get() != buffer)
+ continue;
+
+ overlay_buffer.ref_count_++;
+ break;
+ }
+}
+
+void OverlayBufferManager::RegisterBuffers(
+ const std::vector<OverlayBuffer*>& buffers) {
+ ScopedSpinLock lock(spin_lock_);
+ for (OverlayBuffer* buffer : buffers) {
+ for (Buffer& overlay_buffer : buffers_) {
+ if (overlay_buffer.buffer_.get() != buffer)
+ continue;
+
+ overlay_buffer.ref_count_++;
+ break;
+ }
+ }
+}
+
+void OverlayBufferManager::UnRegisterBuffer(OverlayBuffer* buffer) {
+ ScopedSpinLock lock(spin_lock_);
+ int32_t index = -1;
+ for (Buffer& overlay_buffer : buffers_) {
+ index++;
+ if (overlay_buffer.buffer_.get() != buffer)
+ continue;
+
+ overlay_buffer.ref_count_--;
+ if (overlay_buffer.ref_count_ <= 0) {
+ buffers_.erase(buffers_.begin() + index);
+ }
+
+ break;
+ }
+}
+
+void OverlayBufferManager::UnRegisterBuffers(
+ const std::vector<OverlayBuffer*>& buffers) {
+ ScopedSpinLock lock(spin_lock_);
+ for (OverlayBuffer* buffer : buffers) {
+ int32_t index = -1;
+ for (Buffer& overlay_buffer : buffers_) {
+ index++;
+ if (overlay_buffer.buffer_.get() != buffer)
+ continue;
+
+ overlay_buffer.ref_count_--;
+ if (overlay_buffer.ref_count_ <= 0) {
+ buffers_.erase(buffers_.begin() + index);
+ }
+
+ break;
+ }
+ }
+}
+
+void OverlayBufferManager::SignalBuffersIfReady(
+ std::vector<OverlayLayer>& layers) {
+ ScopedSpinLock lock(spin_lock_);
+ for (OverlayLayer& layer : layers) {
+ if (layer.GetReleaseFenceState() != NativeSync::State::kReady) {
+ continue;
+ }
+
+ OverlayBuffer* buffer = layer.GetBuffer();
+ if (!buffer)
+ continue;
+
+ for (Buffer& overlay_buffer : buffers_) {
+ if (overlay_buffer.buffer_.get() != buffer)
+ continue;
+
+ overlay_buffer.sync_object_.reset(nullptr);
+ break;
+ }
+ }
+}
+
+void OverlayBufferManager::UnRegisterLayerBuffers(
+ std::vector<OverlayLayer>& layers) {
+ ScopedSpinLock lock(spin_lock_);
+ for (OverlayLayer& layer : layers) {
+ OverlayBuffer* buffer = layer.GetBuffer();
+ if (!buffer)
+ continue;
+ int32_t index = -1;
+ for (Buffer& overlay_buffer : buffers_) {
+ index++;
+ if (overlay_buffer.buffer_.get() != buffer)
+ continue;
+
+ overlay_buffer.ref_count_--;
+ layer.MarkBufferReleased();
+ if (overlay_buffer.ref_count_ <= 0) {
+ buffers_.erase(buffers_.begin() + index);
+ }
+
+ break;
+ }
+ }
+}
+
+} // 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.
+*/
+#ifndef COMMON_CORE_OVERLAYBUFFERMANAGER_H_
+#define COMMON_CORE_OVERLAYBUFFERMANAGER_H_
+
+#include <platformdefines.h>
+
+#include <nativebufferhandler.h>
+#include <nativefence.h>
+#include <spinlock.h>
+
+#include <memory>
+#include <vector>
+
+#include "nativesync.h"
+#include "overlaybuffer.h"
+
+namespace hwcomposer {
+
+class NativeBufferHandler;
+class OverlayBufferManager;
+struct OverlayLayer;
+
+struct ImportedBuffer {
+ public:
+ ImportedBuffer(OverlayBuffer* buffer, OverlayBufferManager* buffer_manager,
+ int release_fence)
+ : buffer_(buffer),
+ release_fence_(release_fence),
+ buffer_manager_(buffer_manager) {
+ }
+
+ ~ImportedBuffer();
+
+ OverlayBuffer* buffer_;
+ int release_fence_;
+
+ private:
+ OverlayBufferManager* buffer_manager_;
+};
+
+class OverlayBufferManager {
+ public:
+ OverlayBufferManager() = default;
+ OverlayBufferManager(OverlayBufferManager&& rhs) = default;
+ OverlayBufferManager& operator=(OverlayBufferManager&& other) = default;
+
+ ~OverlayBufferManager();
+
+ bool Initialize(uint32_t gpu_fd);
+
+ // Creates new ImportedBuffer for bo. Also, creates
+ // a sync fence object associated for this buffer.
+ // Sync fence is automatically signalled when buffer
+ // is destroyed. RefCount of buffer is initialized to
+ // 1.
+ ImportedBuffer* CreateBuffer(const HwcBuffer& bo);
+
+ // Creates new ImportedBuffer for handle. Also, creates
+ // a sync fence object associated for this buffer.
+ // Sync fence is automatically signalled when buffer
+ // is destroyed. RefCount of buffer is initialized to
+ // 1.
+ ImportedBuffer* CreateBufferFromNativeHandle(HWCNativeHandle handle);
+
+ // Increments RefCount of buffer by 1. Buffer will not be released
+ // or associated fence object signalled until UnRegisterBuffer
+ // is called and RefCount decreases to zero.
+ void RegisterBuffer(OverlayBuffer* buffer);
+
+ // Decreases RefCount of buffer by 1. Buffer will be released
+ // and associated fence object will be signalled if RefCount
+ // is equal to zero.
+ void UnRegisterBuffer(OverlayBuffer* buffer);
+
+ // Convenient function to call together RegisterBuffer for
+ // OverlayBuffers.
+ void RegisterBuffers(const std::vector<OverlayBuffer*>& buffers);
+
+ // Convenient function to call together UnRegisterBuffers for
+ // OverlayBuffers.
+ void UnRegisterBuffers(const std::vector<OverlayBuffer*>& buffers);
+
+ // Convenient function to signal buffers as free to be re-used
+ // without deleting buffer associated with the layer.
+ void SignalBuffersIfReady(std::vector<OverlayLayer>& layers);
+
+ void UnRegisterLayerBuffers(std::vector<OverlayLayer>& layers);
+
+ NativeBufferHandler* GetNativeBufferHandler() const {
+ return buffer_handler_.get();
+ }
+
+ private:
+ struct Buffer {
+ std::unique_ptr<OverlayBuffer> buffer_;
+ std::unique_ptr<NativeSync> sync_object_;
+ uint32_t ref_count_ = 0;
+ };
+
+ SpinLock spin_lock_;
+ std::vector<Buffer> buffers_;
+ std::unique_ptr<NativeBufferHandler> buffer_handler_;
+};
+
+} // namespace hwcomposer
+#endif // COMMON_CORE_OVERLAYBUFFERMANAGER_H_
namespace hwcomposer {
bool OverlayLayer::operator!=(const OverlayLayer& rhs) const {
- if (buffer_->GetFormat() != rhs.buffer_->GetFormat())
+ OverlayBuffer* buffer = imported_buffer_->buffer_;
+ if (buffer->GetFormat() != rhs.imported_buffer_->buffer_->GetFormat())
return true;
// We expect cursor plane to support alpha always.
- if (!(buffer_->GetUsage() & kLayerCursor)) {
+ if (!(buffer->GetUsage() & kLayerCursor)) {
if (alpha_ != rhs.alpha_)
return true;
}
}
int OverlayLayer::GetReleaseFence() {
- if (!sync_object_) {
- sync_object_.reset(new NativeSync());
- if (!sync_object_->Init()) {
- ETRACE("Failed to create sync object.");
- return -1;
- }
- }
-
- return sync_object_->CreateNextTimelineFence();
+ return imported_buffer_->release_fence_;
}
void OverlayLayer::SetReleaseFenceState(NativeSync::State state) {
- sync_object_->SetState(state);
+ state_ = state;
}
-void OverlayLayer::ReleaseFenceIfReady() {
- if (!sync_object_)
- return;
-
- if (sync_object_->GetState() == NativeSync::State::kReady) {
- sync_object_.reset(nullptr);
- }
+void OverlayLayer::MarkBufferSignalled() {
+ imported_buffer_->release_fence_ = -1;
}
-void OverlayLayer::ReleaseSyncOwnershipAsNeeded(
- std::unique_ptr<NativeSync>& fence) {
- if (sync_object_ &&
- sync_object_->GetState() == NativeSync::State::kSignalOnPageFlipEvent) {
- fence.reset(sync_object_.release());
- }
+void OverlayLayer::MarkBufferReleased() {
+ imported_buffer_->buffer_ = NULL;
}
void OverlayLayer::SetIndex(uint32_t index) {
DUMPTRACE("DstHeight: %d", display_frame_height_);
DUMPTRACE("AquireFence: %d", acquire_fence_.get());
- buffer_->Dump();
+ imported_buffer_->buffer_->Dump();
}
} // namespace hwcomposer
#include <memory>
#include "nativesync.h"
-#include "overlaybuffer.h"
+#include "overlaybuffermanager.h"
namespace hwcomposer {
// longer in use.
int GetReleaseFence();
+ // Release Fence state which will determine
+ // as to when we signal the fence associated
+ // with the buffer of this layer.
void SetReleaseFenceState(NativeSync::State state);
- void ReleaseFenceIfReady();
- void ReleaseSyncOwnershipAsNeeded(std::unique_ptr<NativeSync>& fence);
+ NativeSync::State GetReleaseFenceState() const {
+ return state_;
+ }
+
+ // OverlayBufferManager has signalled the
+ // fence object associated with buffer of this
+ // layer.
+ void MarkBufferSignalled();
+
+ // Only KMSFenceEventHandler should use this.
+ // KMSFenceEventHandler will call this API when
+ // the buffer associated with this layer is no
+ // longer ready by display.
+ void MarkBufferReleased();
void ReleaseAcquireFence() {
acquire_fence_.Reset(-1);
}
OverlayBuffer* GetBuffer() const {
- return buffer_.get();
+ return imported_buffer_->buffer_;
}
- void SetBuffer(OverlayBuffer* buffer) {
- buffer_.reset(buffer);
+ void SetBuffer(ImportedBuffer* buffer) {
+ imported_buffer_.reset(buffer);
}
void SetSourceCrop(const HwcRect<float>& source_crop);
ScopedFd acquire_fence_;
HWCBlending blending_ = HWCBlending::kBlendingNone;
HWCNativeHandle sf_handle_ = 0;
- std::unique_ptr<NativeSync> sync_object_;
- std::unique_ptr<OverlayBuffer> buffer_;
+ NativeSync::State state_ = NativeSync::State::kSignalOnPageFlipEvent;
+ std::unique_ptr<ImportedBuffer> imported_buffer_;
};
} // namespace hwcomposer
static const int32_t kUmPerInch = 25400;
Display::Display(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id)
- : buffer_handler_(NULL),
- crtc_id_(crtc_id),
+ : crtc_id_(crtc_id),
pipe_(pipe_id),
connector_(0),
width_(0),
flip_handler_->SetPowerMode(kOff);
}
-bool Display::Initialize() {
+bool Display::Initialize(OverlayBufferManager *buffer_manager) {
flip_handler_.reset(new PageFlipEventHandler());
- display_queue_.reset(new DisplayQueue(gpu_fd_, crtc_id_));
+ display_queue_.reset(new DisplayQueue(gpu_fd_, crtc_id_, buffer_manager));
return true;
}
bool Display::Connect(const drmModeModeInfo &mode_info,
- const drmModeConnector *connector,
- NativeBufferHandler *buffer_handler) {
+ const drmModeConnector *connector) {
IHOTPLUGEVENTTRACE("Display::Connect recieved.");
// TODO(kalyan): Add support for multi monitor case.
if (connector_ && connector->connector_id == connector_) {
is_connected_ = true;
- if (!display_queue_->Initialize(width_, height_, pipe_, connector_, mode_info,
- buffer_handler)) {
+ if (!display_queue_->Initialize(width_, height_, pipe_, connector_,
+ mode_info)) {
ETRACE("Failed to initialize Display Queue.");
return false;
}
class DisplayPlaneState;
class DisplayPlaneManager;
class DisplayQueue;
-class NativeBufferHandler;
+class OverlayBufferManager;
class GpuDevice;
class NativeSync;
struct HwcLayer;
Display(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
~Display() override;
- bool Initialize() override;
+ bool Initialize(OverlayBufferManager *buffer_manager) override;
DisplayType Type() const override {
return DisplayType::kInternal;
}
bool Connect(const drmModeModeInfo &mode_info,
- const drmModeConnector *connector,
- NativeBufferHandler *buffer_handler) override;
+ const drmModeConnector *connector) override;
bool IsConnected() const override {
return is_connected_;
private:
void ShutDownPipe();
- NativeBufferHandler *buffer_handler_;
uint32_t crtc_id_;
uint32_t pipe_;
uint32_t connector_;
#include "displayplanemanager.h"
-#include <nativebufferhandler.h>
-
#include <drm_fourcc.h>
#include <set>
namespace hwcomposer {
-DisplayPlaneManager::DisplayPlaneManager(int gpu_fd, uint32_t pipe_id,
- uint32_t crtc_id)
- : buffer_handler_(NULL),
+DisplayPlaneManager::DisplayPlaneManager(int gpu_fd, uint32_t crtc_id,
+ OverlayBufferManager *buffer_manager)
+ : buffer_manager_(buffer_manager),
width_(0),
height_(0),
crtc_id_(crtc_id),
- pipe_(pipe_id),
gpu_fd_(gpu_fd),
use_cache_(false) {
}
DisplayPlaneManager::~DisplayPlaneManager() {
}
-bool DisplayPlaneManager::Initialize(NativeBufferHandler *buffer_handler,
- uint32_t width, uint32_t height) {
+bool DisplayPlaneManager::Initialize(uint32_t pipe_id, uint32_t width,
+ uint32_t height) {
ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(gpu_fd_));
if (!plane_resources) {
ETRACE("Failed to get plane resources");
}
uint32_t num_planes = plane_resources->count_planes;
- uint32_t pipe_bit = 1 << pipe_;
+ uint32_t pipe_bit = 1 << pipe_id;
std::set<uint32_t> plane_ids;
for (uint32_t i = 0; i < num_planes; ++i) {
ScopedDrmPlanePtr drm_plane(
[](const std::unique_ptr<DisplayPlane> &l,
const std::unique_ptr<DisplayPlane> &r) { return l->id() < r->id(); });
- buffer_handler_ = buffer_handler;
width_ = width;
height_ = height;
return true;
}
-bool DisplayPlaneManager::BeginFrameUpdate(std::vector<OverlayLayer> *layers) {
+void DisplayPlaneManager::BeginFrameUpdate() {
if (cursor_plane_)
cursor_plane_->SetEnabled(false);
(*i)->SetEnabled(false);
}
- size_t size = layers->size();
- for (size_t layer_index = 0; layer_index < size; layer_index++) {
- OverlayLayer *layer = &layers->at(layer_index);
- HwcBuffer bo;
- if (!buffer_handler_->ImportBuffer(layer->GetNativeHandle(), &bo)) {
- ETRACE("Failed to Import buffer.");
- return false;
- }
-
- OverlayBuffer *buffer = new OverlayBuffer();
- buffer->Initialize(bo);
- layer->SetBuffer(buffer);
- }
-
if (!in_flight_surfaces_.empty())
std::vector<NativeSurface *>().swap(in_flight_surfaces_);
-
- return true;
}
std::tuple<bool, DisplayPlaneStateList> DisplayPlaneManager::ValidateLayers(
if (!surface) {
NativeSurface *new_surface = CreateBackBuffer(width_, height_);
- new_surface->Init(buffer_handler_);
+ new_surface->Init(buffer_manager_);
surfaces_.emplace_back(std::move(new_surface));
surface = surfaces_.back().get();
}
class DisplayPlane;
class DisplayPlaneState;
class GpuDevice;
-class NativeBufferHandler;
+class OverlayBufferManager;
struct OverlayLayer;
class DisplayPlaneManager {
public:
- DisplayPlaneManager(int gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
+ DisplayPlaneManager(int gpu_fd, uint32_t crtc_id,
+ OverlayBufferManager *buffer_manager);
virtual ~DisplayPlaneManager();
- bool Initialize(NativeBufferHandler *buffer_handler, uint32_t width,
- uint32_t height);
+ bool Initialize(uint32_t pipe_id, uint32_t width, uint32_t height);
- bool BeginFrameUpdate(std::vector<OverlayLayer> *layers);
+ void BeginFrameUpdate();
std::tuple<bool, DisplayPlaneStateList> ValidateLayers(
std::vector<OverlayLayer> *layers,
const std::vector<OverlayLayer> *layers,
DisplayPlaneStateList *composition, bool *render_layers);
- NativeBufferHandler *buffer_handler_;
+ OverlayBufferManager *buffer_manager_;
std::vector<std::unique_ptr<NativeSurface>> surfaces_;
std::vector<NativeSurface *> in_flight_surfaces_;
std::unique_ptr<DisplayPlane> primary_plane_;
uint32_t width_;
uint32_t height_;
uint32_t crtc_id_;
- uint32_t pipe_;
uint32_t gpu_fd_;
bool use_cache_;
};
#include <hwcdefs.h>
#include <hwclayer.h>
-#include <nativebufferhandler.h>
#include <vector>
namespace hwcomposer {
-DisplayQueue::DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id)
+DisplayQueue::DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id,
+ OverlayBufferManager* buffer_manager)
: frame_(0),
dpms_prop_(0),
out_fence_ptr_prop_(0),
crtc_prop_(0),
blob_id_(0),
old_blob_id_(0),
- gpu_fd_(gpu_fd) {
+ gpu_fd_(gpu_fd),
+ buffer_manager_(buffer_manager) {
compositor_.Init();
ScopedDrmObjectPropertyPtr crtc_props(
drmModeObjectGetProperties(gpu_fd_, crtc_id_, DRM_MODE_OBJECT_CRTC));
GetDrmObjectProperty("OUT_FENCE_PTR", crtc_props, &out_fence_ptr_prop_);
#endif
memset(&mode_, 0, sizeof(mode_));
+ display_plane_manager_.reset(
+ new DisplayPlaneManager(gpu_fd_, crtc_id_, buffer_manager_));
+
+ kms_fence_handler_.reset(new KMSFenceEventHandler(buffer_manager_));
}
DisplayQueue::~DisplayQueue() {
bool DisplayQueue::Initialize(uint32_t width, uint32_t height, uint32_t pipe,
uint32_t connector,
- const drmModeModeInfo& mode_info,
- NativeBufferHandler* buffer_handler) {
+ const drmModeModeInfo& mode_info) {
frame_ = 0;
previous_layers_.clear();
previous_plane_state_.clear();
- display_plane_manager_.reset(
- new DisplayPlaneManager(gpu_fd_, pipe, crtc_id_));
- if (!display_plane_manager_->Initialize(buffer_handler, width, height)) {
+ if (!display_plane_manager_->Initialize(pipe, width, height)) {
ETRACE("Failed to initialize DisplayQueue Manager.");
return false;
}
- kms_fence_handler_.reset(new KMSFenceEventHandler());
-
connector_ = connector;
mode_ = mode_info;
overlay_layer.SetIndex(layer_index);
overlay_layer.SetAcquireFence(layer->acquire_fence.Release());
layers_rects.emplace_back(layer->GetDisplayFrame());
+ ImportedBuffer* buffer = buffer_manager_->CreateBufferFromNativeHandle(
+ layer->GetNativeHandle());
+ overlay_layer.SetBuffer(buffer);
int ret = layer->release_fence.Reset(overlay_layer.GetReleaseFence());
if (ret < 0)
ETRACE("Failed to create fence for layer, error: %s", PRINTERROR());
}
// Reset any DisplayQueue Manager and Compositor state.
- if (!display_plane_manager_->BeginFrameUpdate(&layers)) {
- ETRACE("Failed to import needed buffers in DisplayQueueManager.");
- return false;
- }
+ display_plane_manager_->BeginFrameUpdate();
uint32_t flags = 0;
if (needs_modeset_) {
}
}
- for (OverlayLayer& layer : layers) {
- layer.ReleaseFenceIfReady();
- }
+ buffer_manager_->SignalBuffersIfReady(layers);
uint64_t fence = 0;
// Do the actual commit.
#ifdef DISABLE_EXPLICIT_SYNC
compositor_.InsertFence(fence);
+ buffer_manager_->UnRegisterLayerBuffers(previous_layers_);
#else
if (fence > 0) {
compositor_.InsertFence(dup(fence));
namespace hwcomposer {
class DisplayPlaneManager;
struct HwcLayer;
-class NativeBufferHandler;
+class OverlayBufferManager;
class PageFlipEventHandler;
class DisplayQueue {
public:
- DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id);
+ DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id,
+ OverlayBufferManager* buffer_manager);
~DisplayQueue();
bool Initialize(uint32_t width, uint32_t height, uint32_t pipe,
- uint32_t connector, const drmModeModeInfo& mode_info,
- NativeBufferHandler* buffer_handler);
+ uint32_t connector, const drmModeModeInfo& mode_info);
bool QueueUpdate(std::vector<HwcLayer*>& source_layers);
bool SetPowerMode(uint32_t power_mode);
std::unique_ptr<DisplayPlaneManager> display_plane_manager_;
std::vector<OverlayLayer> previous_layers_;
DisplayPlaneStateList previous_plane_state_;
+ OverlayBufferManager* buffer_manager_;
};
} // namespace hwcomposer
Headless::~Headless() {
}
-bool Headless::Initialize() {
+bool Headless::Initialize(OverlayBufferManager * /*buffer_manager*/) {
return true;
}
bool Headless::Connect(const drmModeModeInfo & /*mode_info*/,
- const drmModeConnector * /*connector*/,
- NativeBufferHandler * /*buffer_handler*/) {
+ const drmModeConnector * /*connector*/) {
return true;
}
namespace hwcomposer {
-class NativeBufferHandler;
-
class Headless : public NativeDisplay {
public:
Headless(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
~Headless() override;
- bool Initialize() override;
+ bool Initialize(OverlayBufferManager *buffer_manager) override;
DisplayType Type() const override {
return DisplayType::kHeadless;
}
bool Connect(const drmModeModeInfo &mode_info,
- const drmModeConnector *connector,
- NativeBufferHandler *buffer_handler) override;
+ const drmModeConnector *connector) override;
bool IsConnected() const override {
return false;
namespace hwcomposer {
-KMSFenceEventHandler::KMSFenceEventHandler()
- : HWCThread(-8, "KMSFenceEventHandler") {
+KMSFenceEventHandler::KMSFenceEventHandler(OverlayBufferManager* buffer_manager)
+ : HWCThread(-8, "KMSFenceEventHandler"),
+ kms_fence_(0),
+ buffer_manager_(buffer_manager) {
}
KMSFenceEventHandler::~KMSFenceEventHandler() {
std::vector<OverlayLayer>& layers) {
ScopedSpinLock lock(spin_lock_);
for (OverlayLayer& layer : layers) {
- std::unique_ptr<NativeSync> fence;
- layer.ReleaseSyncOwnershipAsNeeded(fence);
- fences_.emplace_back(std::move(fence));
+ OverlayBuffer* buffer = layer.GetBuffer();
+ if (buffer) {
+ buffers_.emplace_back(buffer);
+ // Instead of registering again, we mark the buffer
+ // released in layer so that it's not deleted till we
+ // explicitly unregister the buffer.
+ layer.MarkBufferReleased();
+ }
}
kms_fence_ = kms_fence;
close(kms_fence_);
kms_fence_ = -1;
}
- std::vector<std::unique_ptr<NativeSync>>().swap(fences_);
+
+ buffer_manager_->UnRegisterBuffers(buffers_);
+ std::vector<OverlayBuffer*>().swap(buffers_);
}
} // namespace hwcomposer
class KMSFenceEventHandler : public HWCThread {
public:
- KMSFenceEventHandler();
+ KMSFenceEventHandler(OverlayBufferManager* buffer_manager);
~KMSFenceEventHandler() override;
bool Initialize();
private:
SpinLock spin_lock_;
- std::vector<std::unique_ptr<NativeSync>> fences_;
+ std::vector<OverlayBuffer*> buffers_;
uint64_t kms_fence_;
+ OverlayBufferManager* buffer_manager_;
};
} // namespace hwcomposer
#include <vector>
#include "hwctrace.h"
+#include "overlaybuffermanager.h"
#include "overlaylayer.h"
namespace hwcomposer {
VirtualDisplay::VirtualDisplay(uint32_t gpu_fd,
- NativeBufferHandler *buffer_handler,
+ OverlayBufferManager *buffer_manager,
uint32_t pipe_id, uint32_t crtc_id)
: Headless(gpu_fd, pipe_id, crtc_id),
output_handle_(0),
acquire_fence_(-1),
- buffer_handler_(buffer_handler),
+ buffer_manager_(buffer_manager),
width_(0),
height_(0) {
}
bool VirtualDisplay::Present(std::vector<HwcLayer *> &source_layers) {
CTRACE();
std::vector<OverlayLayer> layers;
- std::vector<OverlayBuffer> buffers;
std::vector<HwcRect<int>> layers_rects;
std::vector<size_t> index;
int ret = 0;
overlay_layer.SetAcquireFence(layer->acquire_fence.Release());
layers_rects.emplace_back(layer->GetDisplayFrame());
index.emplace_back(layer_index);
- buffers.emplace_back();
- OverlayBuffer *buffer = new OverlayBuffer();
- buffer->InitializeFromNativeHandle(layer->GetNativeHandle(),
- buffer_handler_);
+ ImportedBuffer *buffer =
+ buffer_manager_->CreateBufferFromNativeHandle(layer->GetNativeHandle());
overlay_layer.SetBuffer(buffer);
}
int retire_fence;
// Prepare for final composition.
- if (!compositor_.DrawOffscreen(layers, layers_rects, index, buffer_handler_,
+ if (!compositor_.DrawOffscreen(layers, layers_rects, index, buffer_manager_,
width_, height_, output_handle_,
&retire_fence)) {
ETRACE("Failed to prepare for the frame composition ret=%d", ret);
#include "headless.h"
-#include <nativebufferhandler.h>
-
#include <vector>
#include "compositor.h"
namespace hwcomposer {
struct HwcLayer;
+class OverlayBufferManager;
class VirtualDisplay : public Headless {
public:
- VirtualDisplay(uint32_t gpu_fd, NativeBufferHandler *buffer_handler,
+ VirtualDisplay(uint32_t gpu_fd, OverlayBufferManager *buffer_manager,
uint32_t pipe_id, uint32_t crtc_id);
~VirtualDisplay() override;
private:
HWCNativeHandle output_handle_;
int32_t acquire_fence_;
- NativeBufferHandler *buffer_handler_;
+ OverlayBufferManager *buffer_manager_;
Compositor compositor_;
uint32_t width_;
uint32_t height_;
namespace hwcomposer {
struct HwcLayer;
class GpuDevice;
-class NativeBufferHandler;
+class OverlayBufferManager;
class VsyncCallback {
public:
virtual ~NativeDisplay() {
}
- virtual bool Initialize() = 0;
+ virtual bool Initialize(OverlayBufferManager *buffer_manager) = 0;
virtual DisplayType Type() const = 0;
protected:
virtual uint32_t CrtcId() const = 0;
virtual bool Connect(const drmModeModeInfo &mode_info,
- const drmModeConnector *connector,
- NativeBufferHandler *buffer_handler) = 0;
+ const drmModeConnector *connector) = 0;
virtual bool IsConnected() const = 0;