sde: Add support for DisplayEventHandler
- Add DisplayEventHandler to receive VSync event from driver. - Add hooks to enable/disable VSync from client. - Propogate VSync timestamp to the client Change-Id: I27ea9773c424d8ad85f11f292ddd8792564bbcdc
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
eb547a0340
commit
edb8bc82ff
@@ -274,7 +274,7 @@ class DeviceInterface {
|
|||||||
|
|
||||||
@return \link DisplayError \endlink
|
@return \link DisplayError \endlink
|
||||||
*/
|
*/
|
||||||
virtual DisplayError SetVSyncState(bool enabled) = 0;
|
virtual DisplayError SetVSyncState(bool enable) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~DeviceInterface() { }
|
virtual ~DeviceInterface() { }
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
|
|
||||||
namespace sde {
|
namespace sde {
|
||||||
|
|
||||||
|
const int kThreadPriorityUrgent = -9;
|
||||||
|
|
||||||
typedef void * Handle;
|
typedef void * Handle;
|
||||||
|
|
||||||
} // namespace sde
|
} // namespace sde
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ DeviceBase::DeviceBase(DeviceType device_type, DeviceEventHandler *event_handler
|
|||||||
: device_type_(device_type), event_handler_(event_handler), hw_block_type_(hw_block_type),
|
: device_type_(device_type), event_handler_(event_handler), hw_block_type_(hw_block_type),
|
||||||
hw_intf_(hw_intf), comp_manager_(comp_manager), state_(kStateOff), hw_device_(0),
|
hw_intf_(hw_intf), comp_manager_(comp_manager), state_(kStateOff), hw_device_(0),
|
||||||
comp_mgr_device_(0), device_attributes_(NULL), num_modes_(0), active_mode_index_(0),
|
comp_mgr_device_(0), device_attributes_(NULL), num_modes_(0), active_mode_index_(0),
|
||||||
pending_commit_(false) {
|
pending_commit_(false), vsync_enable_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayError DeviceBase::Init() {
|
DisplayError DeviceBase::Init() {
|
||||||
@@ -46,7 +46,7 @@ DisplayError DeviceBase::Init() {
|
|||||||
|
|
||||||
DisplayError error = kErrorNone;
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
error = hw_intf_->Open(hw_block_type_, &hw_device_);
|
error = hw_intf_->Open(hw_block_type_, &hw_device_, this);
|
||||||
if (UNLIKELY(error != kErrorNone)) {
|
if (UNLIKELY(error != kErrorNone)) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -267,9 +267,30 @@ DisplayError DeviceBase::SetConfig(uint32_t mode) {
|
|||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayError DeviceBase::SetVSyncState(bool enabled) {
|
DisplayError DeviceBase::SetVSyncState(bool enable) {
|
||||||
SCOPE_LOCK(locker_);
|
SCOPE_LOCK(locker_);
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
if (vsync_enable_ != enable) {
|
||||||
|
error = hw_intf_->SetVSyncState(hw_device_, enable);
|
||||||
|
if (error == kErrorNone) {
|
||||||
|
vsync_enable_ = enable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError DeviceBase::VSync(int64_t timestamp) {
|
||||||
|
if (vsync_enable_) {
|
||||||
|
DeviceEventVSync vsync;
|
||||||
|
vsync.timestamp = timestamp;
|
||||||
|
event_handler_->VSync(vsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayError DeviceBase::Blank(bool blank) {
|
||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
namespace sde {
|
namespace sde {
|
||||||
|
|
||||||
class DeviceBase : public DeviceInterface, DumpImpl {
|
class DeviceBase : public DeviceInterface, DumpImpl, HWEventHandler {
|
||||||
public:
|
public:
|
||||||
DeviceBase(DeviceType device_type, DeviceEventHandler *event_handler,
|
DeviceBase(DeviceType device_type, DeviceEventHandler *event_handler,
|
||||||
HWBlockType hw_block_type, HWInterface *hw_intf, CompManager *comp_manager);
|
HWBlockType hw_block_type, HWInterface *hw_intf, CompManager *comp_manager);
|
||||||
@@ -50,11 +50,15 @@ class DeviceBase : public DeviceInterface, DumpImpl {
|
|||||||
virtual DisplayError GetVSyncState(bool *enabled);
|
virtual DisplayError GetVSyncState(bool *enabled);
|
||||||
virtual DisplayError SetDeviceState(DeviceState state);
|
virtual DisplayError SetDeviceState(DeviceState state);
|
||||||
virtual DisplayError SetConfig(uint32_t mode);
|
virtual DisplayError SetConfig(uint32_t mode);
|
||||||
virtual DisplayError SetVSyncState(bool enabled);
|
virtual DisplayError SetVSyncState(bool enable);
|
||||||
|
|
||||||
// DumpImpl method
|
// DumpImpl method
|
||||||
virtual uint32_t GetDump(uint8_t *buffer, uint32_t length);
|
virtual uint32_t GetDump(uint8_t *buffer, uint32_t length);
|
||||||
|
|
||||||
|
// Implement the HWEventHandlers
|
||||||
|
virtual DisplayError VSync(int64_t timestamp);
|
||||||
|
virtual DisplayError Blank(bool blank);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Locker locker_;
|
Locker locker_;
|
||||||
DeviceType device_type_;
|
DeviceType device_type_;
|
||||||
@@ -70,6 +74,7 @@ class DeviceBase : public DeviceInterface, DumpImpl {
|
|||||||
uint32_t active_mode_index_;
|
uint32_t active_mode_index_;
|
||||||
HWLayers hw_layers_;
|
HWLayers hw_layers_;
|
||||||
bool pending_commit_;
|
bool pending_commit_;
|
||||||
|
bool vsync_enable_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sde
|
} // namespace sde
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <utils/constants.h>
|
#include <utils/constants.h>
|
||||||
|
|
||||||
#include "hw_framebuffer.h"
|
#include "hw_framebuffer.h"
|
||||||
@@ -45,15 +48,20 @@
|
|||||||
extern int virtual_ioctl(int fd, int cmd, ...);
|
extern int virtual_ioctl(int fd, int cmd, ...);
|
||||||
extern int virtual_open(const char *file_name, int access, ...);
|
extern int virtual_open(const char *file_name, int access, ...);
|
||||||
extern int virtual_close(int fd);
|
extern int virtual_close(int fd);
|
||||||
|
extern int virtual_poll(struct pollfd *fds, nfds_t num, int timeout);
|
||||||
|
extern ssize_t virtual_pread(int fd, void *data, size_t count, off_t offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace sde {
|
namespace sde {
|
||||||
|
|
||||||
HWFrameBuffer::HWFrameBuffer() {
|
HWFrameBuffer::HWFrameBuffer() : event_thread_name_("SDE_EventThread"), fake_vsync_(false),
|
||||||
// Point to actual driver interfaces.
|
exit_threads_(false) {
|
||||||
|
// Pointer to actual driver interfaces.
|
||||||
ioctl_ = ::ioctl;
|
ioctl_ = ::ioctl;
|
||||||
open_ = ::open;
|
open_ = ::open;
|
||||||
close_ = ::close;
|
close_ = ::close;
|
||||||
|
poll_ = ::poll;
|
||||||
|
pread_ = ::pread;
|
||||||
|
|
||||||
#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
|
#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
|
||||||
// If debug property to use virtual driver is set, point to virtual driver interfaces.
|
// If debug property to use virtual driver is set, point to virtual driver interfaces.
|
||||||
@@ -61,15 +69,83 @@ HWFrameBuffer::HWFrameBuffer() {
|
|||||||
ioctl_ = virtual_ioctl;
|
ioctl_ = virtual_ioctl;
|
||||||
open_ = virtual_open;
|
open_ = virtual_open;
|
||||||
close_ = virtual_close;
|
close_ = virtual_close;
|
||||||
|
poll_ = virtual_poll;
|
||||||
|
pread_ = virtual_pread;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayError HWFrameBuffer::Init() {
|
DisplayError HWFrameBuffer::Init() {
|
||||||
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
|
// TODO(user): Need to read the fbnode info, hw capabilities here
|
||||||
|
|
||||||
|
// Open nodes for polling
|
||||||
|
char node_path[kMaxStringLength] = {0};
|
||||||
|
char data[kMaxStringLength] = {0};
|
||||||
|
const char* event_name[kNumDisplayEvents] = {"vsync_event", "show_blank_event"};
|
||||||
|
|
||||||
|
for (int display = 0; display < kNumPhysicalDisplays; display++) {
|
||||||
|
for (int event = 0; event < kNumDisplayEvents; event++) {
|
||||||
|
poll_fds_[display][event].fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fake_vsync_) {
|
||||||
|
for (int display = 0; display < kNumPhysicalDisplays; display++) {
|
||||||
|
for (int event = 0; event < kNumDisplayEvents; event++) {
|
||||||
|
pollfd &poll_fd = poll_fds_[display][event];
|
||||||
|
|
||||||
|
snprintf(node_path, sizeof(node_path), "/sys/class/graphics/fb%d/%s",
|
||||||
|
(display == 0) ? 0 : 1/*TODO(user): HDMI fb node index*/, event_name[event]);
|
||||||
|
|
||||||
|
poll_fd.fd = open_(node_path, O_RDONLY);
|
||||||
|
if (poll_fd.fd < 0) {
|
||||||
|
DLOGE("open failed for display=%d event=%zu, error=%s", display, event, strerror(errno));
|
||||||
|
error = kErrorHardware;
|
||||||
|
goto CleanupOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read once on all fds to clear data on all fds.
|
||||||
|
pread_(poll_fd.fd, data , kMaxStringLength, 0);
|
||||||
|
poll_fd.events = POLLPRI | POLLERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the Event thread
|
||||||
|
if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) {
|
||||||
|
DLOGE("Failed to start %s, error = %s", event_thread_name_);
|
||||||
|
error = kErrorResources;
|
||||||
|
goto CleanupOnError;
|
||||||
|
}
|
||||||
|
|
||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
|
|
||||||
|
CleanupOnError:
|
||||||
|
// Close all poll fds
|
||||||
|
for (int display = 0; display < kNumPhysicalDisplays; display++) {
|
||||||
|
for (int event = 0; event < kNumDisplayEvents; event++) {
|
||||||
|
int &fd = poll_fds_[display][event].fd;
|
||||||
|
if (fd >= 0) {
|
||||||
|
close_(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayError HWFrameBuffer::Deinit() {
|
DisplayError HWFrameBuffer::Deinit() {
|
||||||
|
exit_threads_ = true;
|
||||||
|
pthread_join(event_thread_, NULL);
|
||||||
|
|
||||||
|
for (int display = 0; display < kNumPhysicalDisplays; display++) {
|
||||||
|
for (int event = 0; event < kNumDisplayEvents; event++) {
|
||||||
|
close(poll_fds_[display][event].fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +167,7 @@ DisplayError HWFrameBuffer::GetHWCapabilities(HWResourceInfo *hw_res_info) {
|
|||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayError HWFrameBuffer::Open(HWBlockType type, Handle *device) {
|
DisplayError HWFrameBuffer::Open(HWBlockType type, Handle *device, HWEventHandler* eventhandler) {
|
||||||
DisplayError error = kErrorNone;
|
DisplayError error = kErrorNone;
|
||||||
|
|
||||||
HWContext *hw_context = new HWContext();
|
HWContext *hw_context = new HWContext();
|
||||||
@@ -119,6 +195,8 @@ DisplayError HWFrameBuffer::Open(HWBlockType type, Handle *device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*device = hw_context;
|
*device = hw_context;
|
||||||
|
event_handler_[device_id] = eventhandler;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +294,17 @@ DisplayError HWFrameBuffer::Standby(Handle device) {
|
|||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayError HWFrameBuffer::SetVSyncState(Handle device, bool enable) {
|
||||||
|
HWContext *hw_context = reinterpret_cast<HWContext *>(device);
|
||||||
|
int vsync_on = enable ? 1 : 0;
|
||||||
|
if (ioctl_(hw_context->device_fd, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_on) == -1) {
|
||||||
|
IOCTL_LOGE(MSMFB_OVERLAY_VSYNC_CTRL);
|
||||||
|
return kErrorHardware;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
DisplayError HWFrameBuffer::Validate(Handle device, HWLayers *hw_layers) {
|
DisplayError HWFrameBuffer::Validate(Handle device, HWLayers *hw_layers) {
|
||||||
HWContext *hw_context = reinterpret_cast<HWContext *>(device);
|
HWContext *hw_context = reinterpret_cast<HWContext *>(device);
|
||||||
|
|
||||||
@@ -357,5 +446,86 @@ void HWFrameBuffer::SetRect(mdp_rect *target, const LayerRect &source) {
|
|||||||
target->h = INT(floorf(source.bottom)) - target->y;
|
target->h = INT(floorf(source.bottom)) - target->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sde
|
void* HWFrameBuffer::DisplayEventThread(void *context) {
|
||||||
|
if (context) {
|
||||||
|
return reinterpret_cast<HWFrameBuffer *>(context)->DisplayEventThreadHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* HWFrameBuffer::DisplayEventThreadHandler() {
|
||||||
|
char data[kMaxStringLength] = {0};
|
||||||
|
|
||||||
|
prctl(PR_SET_NAME, event_thread_name_, 0, 0, 0);
|
||||||
|
setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
|
||||||
|
|
||||||
|
if (fake_vsync_) {
|
||||||
|
while (!exit_threads_) {
|
||||||
|
// Fake vsync is used only when set explicitly through a property(todo) or when
|
||||||
|
// the vsync timestamp node cannot be opened at bootup. There is no
|
||||||
|
// fallback to fake vsync from the true vsync loop, ever, as the
|
||||||
|
// condition can easily escape detection.
|
||||||
|
// Also, fake vsync is delivered only for the primary display.
|
||||||
|
usleep(16666);
|
||||||
|
STRUCT_VAR(timeval, time_now);
|
||||||
|
gettimeofday(&time_now, NULL);
|
||||||
|
uint64_t ts = uint64_t(time_now.tv_sec)*1000000000LL +uint64_t(time_now.tv_usec)*1000LL;
|
||||||
|
|
||||||
|
// Send Vsync event for primary display(0)
|
||||||
|
event_handler_[0]->VSync(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (HWFrameBuffer::*EventHandler)(int, char*);
|
||||||
|
EventHandler event_handler[kNumDisplayEvents] = { &HWFrameBuffer::HandleVSync,
|
||||||
|
&HWFrameBuffer::HandleBlank };
|
||||||
|
|
||||||
|
while (!exit_threads_) {
|
||||||
|
int error = poll_(poll_fds_[0], kNumPhysicalDisplays * kNumDisplayEvents, -1);
|
||||||
|
if (error < 0) {
|
||||||
|
DLOGE("poll failed errno: %s", strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int display = 0; display < kNumPhysicalDisplays; display++) {
|
||||||
|
for (int event = 0; event < kNumDisplayEvents; event++) {
|
||||||
|
pollfd &poll_fd = poll_fds_[display][event];
|
||||||
|
|
||||||
|
if (poll_fd.revents & POLLPRI) {
|
||||||
|
ssize_t length = pread_(poll_fd.fd, data, kMaxStringLength, 0);
|
||||||
|
if (length < 0) {
|
||||||
|
// If the read was interrupted - it is not a fatal error, just continue.
|
||||||
|
DLOGE("Failed to read event:%zu for display=%d : %s", event, display, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
(this->*event_handler[event])(display, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit(0);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWFrameBuffer::HandleVSync(int display_id, char *data) {
|
||||||
|
int64_t timestamp = 0;
|
||||||
|
if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
|
||||||
|
timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
|
||||||
|
}
|
||||||
|
event_handler_[display_id]->VSync(timestamp);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWFrameBuffer::HandleBlank(int display_id, char* data) {
|
||||||
|
// TODO(user): Need to send blank Event
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sde
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#define __HW_FRAMEBUFFER_H__
|
#define __HW_FRAMEBUFFER_H__
|
||||||
|
|
||||||
#include <linux/msm_mdp.h>
|
#include <linux/msm_mdp.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "hw_interface.h"
|
#include "hw_interface.h"
|
||||||
|
|
||||||
namespace sde {
|
namespace sde {
|
||||||
@@ -36,14 +38,15 @@ class HWFrameBuffer : public HWInterface {
|
|||||||
DisplayError Init();
|
DisplayError Init();
|
||||||
DisplayError Deinit();
|
DisplayError Deinit();
|
||||||
virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info);
|
virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info);
|
||||||
virtual DisplayError Open(HWBlockType type, Handle *device);
|
virtual DisplayError Open(HWBlockType type, Handle *device, HWEventHandler *eventhandler);
|
||||||
virtual DisplayError Close(Handle device);
|
virtual DisplayError Close(Handle device);
|
||||||
virtual DisplayError GetNumDeviceAttributes(Handle device, uint32_t *count);
|
virtual DisplayError GetNumDeviceAttributes(Handle device, uint32_t *count);
|
||||||
virtual DisplayError GetDeviceAttributes(Handle device, HWDeviceAttributes *device_attributes,
|
virtual DisplayError GetDeviceAttributes(Handle device, HWDeviceAttributes *device_attributes,
|
||||||
uint32_t mode);
|
uint32_t mode);
|
||||||
virtual DisplayError PowerOn(Handle device);
|
virtual DisplayError PowerOn(Handle device);
|
||||||
virtual DisplayError PowerOff(Handle device);
|
virtual DisplayError PowerOff(Handle device);
|
||||||
virtual DisplayError Doze(Handle device);
|
virtual DisplayError Doze(Handle device);
|
||||||
|
virtual DisplayError SetVSyncState(Handle device, bool enable);
|
||||||
virtual DisplayError Standby(Handle device);
|
virtual DisplayError Standby(Handle device);
|
||||||
virtual DisplayError Validate(Handle device, HWLayers *hw_layers);
|
virtual DisplayError Validate(Handle device, HWLayers *hw_layers);
|
||||||
virtual DisplayError Commit(Handle device, HWLayers *hw_layers);
|
virtual DisplayError Commit(Handle device, HWLayers *hw_layers);
|
||||||
@@ -54,14 +57,40 @@ class HWFrameBuffer : public HWInterface {
|
|||||||
int device_fd;
|
int device_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kHWEventVSync,
|
||||||
|
kHWEventBlank,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int kMaxStringLength = 1024;
|
||||||
|
static const int kNumPhysicalDisplays = 2;
|
||||||
|
static const int kNumDisplayEvents = 2;
|
||||||
|
|
||||||
inline void SetFormat(uint32_t *target, const LayerBufferFormat &source);
|
inline void SetFormat(uint32_t *target, const LayerBufferFormat &source);
|
||||||
inline void SetBlending(uint32_t *target, const LayerBlending &source);
|
inline void SetBlending(uint32_t *target, const LayerBlending &source);
|
||||||
inline void SetRect(mdp_rect *target, const LayerRect &source);
|
inline void SetRect(mdp_rect *target, const LayerRect &source);
|
||||||
|
|
||||||
// For dynamically linking virtual driver
|
// Event Thread to receive vsync/blank events
|
||||||
|
static void* DisplayEventThread(void *context);
|
||||||
|
void* DisplayEventThreadHandler();
|
||||||
|
|
||||||
|
void HandleVSync(int display_id, char *data);
|
||||||
|
void HandleBlank(int display_id, char *data);
|
||||||
|
|
||||||
|
// Pointers to system calls which are either mapped to actual system call or virtual driver.
|
||||||
int (*ioctl_)(int, int, ...);
|
int (*ioctl_)(int, int, ...);
|
||||||
int (*open_)(const char *, int, ...);
|
int (*open_)(const char *, int, ...);
|
||||||
int (*close_)(int);
|
int (*close_)(int);
|
||||||
|
int (*poll_)(struct pollfd *, nfds_t, int);
|
||||||
|
ssize_t (*pread_)(int, void *, size_t, off_t);
|
||||||
|
|
||||||
|
// Store the Device EventHandlers - used for callback
|
||||||
|
HWEventHandler *event_handler_[kNumPhysicalDisplays];
|
||||||
|
pollfd poll_fds_[kNumPhysicalDisplays][kNumDisplayEvents];
|
||||||
|
pthread_t event_thread_;
|
||||||
|
const char *event_thread_name_;
|
||||||
|
bool fake_vsync_;
|
||||||
|
bool exit_threads_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sde
|
} // namespace sde
|
||||||
|
|||||||
@@ -99,12 +99,21 @@ struct HWDeviceAttributes : DeviceConfigVariableInfo {
|
|||||||
HWDeviceAttributes() : is_device_split(false), split_left(0) { }
|
HWDeviceAttributes() : is_device_split(false), split_left(0) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// HWEventHandler - Implemented in DeviceBase and HWInterface implementation
|
||||||
|
class HWEventHandler {
|
||||||
|
public:
|
||||||
|
virtual DisplayError VSync(int64_t timestamp) = 0;
|
||||||
|
virtual DisplayError Blank(bool blank)= 0;
|
||||||
|
protected:
|
||||||
|
virtual ~HWEventHandler() {}
|
||||||
|
};
|
||||||
|
|
||||||
class HWInterface {
|
class HWInterface {
|
||||||
public:
|
public:
|
||||||
static DisplayError Create(HWInterface **intf);
|
static DisplayError Create(HWInterface **intf);
|
||||||
static DisplayError Destroy(HWInterface *intf);
|
static DisplayError Destroy(HWInterface *intf);
|
||||||
virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info) = 0;
|
virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info) = 0;
|
||||||
virtual DisplayError Open(HWBlockType type, Handle *device) = 0;
|
virtual DisplayError Open(HWBlockType type, Handle *device, HWEventHandler *eventhandler) = 0;
|
||||||
virtual DisplayError Close(Handle device) = 0;
|
virtual DisplayError Close(Handle device) = 0;
|
||||||
virtual DisplayError GetNumDeviceAttributes(Handle device, uint32_t *count) = 0;
|
virtual DisplayError GetNumDeviceAttributes(Handle device, uint32_t *count) = 0;
|
||||||
virtual DisplayError GetDeviceAttributes(Handle device, HWDeviceAttributes *device_attributes,
|
virtual DisplayError GetDeviceAttributes(Handle device, HWDeviceAttributes *device_attributes,
|
||||||
@@ -112,6 +121,7 @@ class HWInterface {
|
|||||||
virtual DisplayError PowerOn(Handle device) = 0;
|
virtual DisplayError PowerOn(Handle device) = 0;
|
||||||
virtual DisplayError PowerOff(Handle device) = 0;
|
virtual DisplayError PowerOff(Handle device) = 0;
|
||||||
virtual DisplayError Doze(Handle device) = 0;
|
virtual DisplayError Doze(Handle device) = 0;
|
||||||
|
virtual DisplayError SetVSyncState(Handle device, bool enable) = 0;
|
||||||
virtual DisplayError Standby(Handle device) = 0;
|
virtual DisplayError Standby(Handle device) = 0;
|
||||||
virtual DisplayError Validate(Handle device, HWLayers *hw_layers) = 0;
|
virtual DisplayError Validate(Handle device, HWLayers *hw_layers) = 0;
|
||||||
virtual DisplayError Commit(Handle device, HWLayers *hw_layers) = 0;
|
virtual DisplayError Commit(Handle device, HWLayers *hw_layers) = 0;
|
||||||
|
|||||||
@@ -144,12 +144,18 @@ int HWCSink::SetState(DeviceState state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DisplayError HWCSink::VSync(const DeviceEventVSync &vsync) {
|
DisplayError HWCSink::VSync(const DeviceEventVSync &vsync) {
|
||||||
(*hwc_procs_)->vsync(*hwc_procs_, id_, vsync.timestamp);
|
if (*hwc_procs_) {
|
||||||
|
(*hwc_procs_)->vsync(*hwc_procs_, id_, vsync.timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayError HWCSink::Refresh() {
|
DisplayError HWCSink::Refresh() {
|
||||||
(*hwc_procs_)->invalidate(*hwc_procs_);
|
if (*hwc_procs_) {
|
||||||
|
(*hwc_procs_)->invalidate(*hwc_procs_);
|
||||||
|
}
|
||||||
|
|
||||||
return kErrorNone;
|
return kErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user