#include "DSDisplayDeviceHWCTDMImpl.h"
#include "DSDisplayDeviceHWCWindowTDMImpl.h"
#include "DSDebugLog.h"
+#include <cstring>
namespace display_server
{
+
DSDisplayDeviceHWCTDMImpl::DSDisplayDeviceHWCTDMImpl(tdm_hwc *thwc)
- : __thwc(thwc)
+ : __thwc(thwc),
+ __bufferQueue(nullptr)
+{}
+
+DSDisplayDeviceHWCTDMImpl::~DSDisplayDeviceHWCTDMImpl()
+{
+ clearVisibleHWCWindows();
+}
+
+std::shared_ptr<IDSBufferQueue> DSDisplayDeviceHWCTDMImpl::getTargetBufferQueue()
{
+ tdm_error terror;
+ tbm_surface_queue_h tqueue;
+
+ if (__bufferQueue) {
+ DSLOG_INF("TDM_HWC", "return the existed IDSBufferQueue.");
+ return __bufferQueue;
+ }
+
+ tqueue = tdm_hwc_get_client_target_buffer_queue(__thwc, &terror);
+ if (terror != TDM_ERROR_NONE) {
+ DSLOG_ERR("HWCTDM", "tdm_hwc_get_client_target_buffer_queue fails.\n");
+ }
+ __bufferQueue = std::make_shared<DSBufferQueueTBMImpl>(tqueue);
+
+ return __bufferQueue;
}
-DSDisplayDeviceHWCTDMImpl::~DSDisplayDeviceHWCTDMImpl()
+
+bool DSDisplayDeviceHWCTDMImpl::setTargetBuffer(std::shared_ptr<IDSBuffer> buffer)
{
+ tdm_error terror;
+ tdm_region fb_damage;
+ std::memset(&fb_damage, 0, sizeof (tdm_region));
+
+ terror = tdm_hwc_set_client_target_buffer(__thwc, (tbm_surface_h)buffer->getNativeBuffer(), fb_damage);
+ if (terror != TDM_ERROR_NONE) {
+ DSLOG_ERR("TDM_HWC", "tdm_hwc_set_client_target_buffer fails.");
+ return false;
+ }
+ return true;
}
-IDSDisplayDeviceHWCWindow *DSDisplayDeviceHWCTDMImpl::createHWCWindow()
+std::shared_ptr<IDSDisplayDeviceHWCWindow> DSDisplayDeviceHWCTDMImpl::makeHWCWindow()
{
+ std::shared_ptr<IDSDisplayDeviceHWCWindow> deviceHWCWindow;
tdm_error terror;
tdm_hwc_window *twindow;
- IDSDisplayDeviceHWCWindow *deviceHWCWindow;
twindow = tdm_hwc_create_window(__thwc, &terror);
if (!twindow) {
- DSLOG_ERR("TDM HWCWindow", "tdm_hwc_create_window fails.\n");
+ DSLOG_ERR("HWCTDM", "tdm_hwc_create_window fails.\n");
return nullptr;
}
- deviceHWCWindow = new DSDisplayDeviceHWCWindowTDMImpl(twindow);
+ deviceHWCWindow = std::make_shared<DSDisplayDeviceHWCWindowTDMImpl>(twindow);
if (!deviceHWCWindow) {
- DSLOG_ERR("TDM HWCWindow", "new DSDisplayDeviceHWCWindowTDMImpl fails.\n");
+ DSLOG_ERR("HWCTDM", "new DSDisplayDeviceHWCWindowTDMImpl fails.\n");
return nullptr;
}
- __deviceHWCWindowList.push_back(deviceHWCWindow);
-
return deviceHWCWindow;
}
-void DSDisplayDeviceHWCTDMImpl::destroyHWCWindow(IDSDisplayDeviceHWCWindow *deviceHWCWindow)
+bool DSDisplayDeviceHWCTDMImpl::addVisibleHWCWindow(std::shared_ptr<IDSDisplayDeviceHWCWindow> deviceHWCWindow)
+{
+ __visibleDeviceHWCWindowList.push_back(deviceHWCWindow);
+
+ return true;
+}
+
+bool DSDisplayDeviceHWCTDMImpl::removeVisibleHWCWindow(std::shared_ptr<IDSDisplayDeviceHWCWindow> deviceHWCWindow)
+{
+ __visibleDeviceHWCWindowList.remove(deviceHWCWindow);
+
+ return true;
+}
+
+void DSDisplayDeviceHWCTDMImpl::clearVisibleHWCWindows()
{
- delete deviceHWCWindow;
- __deviceHWCWindowList.remove(deviceHWCWindow);
+ __visibleDeviceHWCWindowList.clear();
}
bool DSDisplayDeviceHWCTDMImpl::commit()
{
tdm_error terror;
- int numVisibleHWCWins = __deviceHWCWindowList.size(); //TODO: need to fix. change it to visible windows list. __deviceHWCWindowList is not the visible window list.
- DSDisplayDeviceHWCWindowTDMImpl *hwcWinsImpl;
- uint32_t numTypes;
+ uint32_t numChanges;
- // get the thwc_windows to request validate.
+ if (!__validate(numChanges)) {
+ DSLOG_ERR("HWCTDM", "__validate fails.\n");
+ return false;
+ }
+
+ if (numChanges > 0) {
+ if (!__updateChanges(numChanges)) {
+ DSLOG_ERR("HWCTDM", "__updateChanges fails.\n");
+ return false;
+ }
+ }
+
+ if (!__acceptValidation()) {
+ DSLOG_ERR("HWCTDM", "__acceptValidation fails.\n");
+ return false;
+ }
+
+ //TODO: tdm_hwc_commit
+ terror = tdm_hwc_commit(__thwc, 0, NULL, NULL);
+ if (terror != TDM_ERROR_NONE) {
+ DSLOG_ERR("HWCTDM", "tdm_hwc_commit fails.");
+ return false;
+ }
+
+ return true;
+}
+
+bool DSDisplayDeviceHWCTDMImpl::__validate(uint32_t &numChanges)
+{
+ int numVisibleHWCWins = __visibleDeviceHWCWindowList.size();
+ tdm_error terror;
tdm_hwc_window **thwc_windows;
+ int i = 0;
+
+ // get the thwc_windows to request validate.
thwc_windows = (tdm_hwc_window **)calloc(numVisibleHWCWins, sizeof(tdm_hwc_window *));
if (thwc_windows == nullptr) {
DSLOG_ERR("TDM_HWC", "calloc thwc_windows fails.");
return false;
}
- int i = 0;
- for (auto *hwcwins : __deviceHWCWindowList) {
- hwcWinsImpl = (DSDisplayDeviceHWCWindowTDMImpl *)hwcwins;
- thwc_windows[i++] = hwcWinsImpl->getTDMHWCWindow();
+ for (auto &&deviceHWCWindow : __visibleDeviceHWCWindowList) {
+ auto deviceHWCWindowTDM = std::dynamic_pointer_cast<DSDisplayDeviceHWCWindowTDMImpl>(deviceHWCWindow);
+ thwc_windows[i++] = deviceHWCWindowTDM->getNativeHWCWindow();
}
// validate thwc_windows
- terror = tdm_hwc_validate(__thwc, thwc_windows, numVisibleHWCWins, &numTypes);
+ terror = tdm_hwc_validate(__thwc, thwc_windows, numVisibleHWCWins, &numChanges);
if (terror != TDM_ERROR_NONE) {
DSLOG_ERR("TDM_HWC", "tdm_hwc_validate fails.");
free(thwc_windows);
free(thwc_windows);
- // get changed_types
+ return true;
+}
+
+bool DSDisplayDeviceHWCTDMImpl::__updateChanges(uint32_t numChanges)
+{
+ tdm_error terror;
tdm_hwc_window **changed_thwc_window = NULL;
tdm_hwc_window_composition *tcomposition_types = NULL;
- uint32_t numChanges = 0;
- if (numTypes > 0) {
- changed_thwc_window = (tdm_hwc_window **)calloc(numTypes, sizeof(tdm_hwc_window *));
- if (changed_thwc_window == nullptr) {
- DSLOG_ERR("TDM_HWC", "calloc changed_thwc_window fails.");
- return false;
- }
-
- tcomposition_types = (tdm_hwc_window_composition *)calloc(numTypes, sizeof(tdm_hwc_window_composition));
- if (tcomposition_types == nullptr) {
- DSLOG_ERR("TDM_HWC", "calloc changed_thwc_window fails.");
- free(changed_thwc_window);
- return false;
- }
-
- terror = tdm_hwc_get_changed_composition_types(__thwc, &numChanges, changed_thwc_window, tcomposition_types);
- if (terror != TDM_ERROR_NONE) {
- DSLOG_ERR("TDM_HWC", "tdm_hwc_get_changed_composition_types fails.");
- free(tcomposition_types);
- free(changed_thwc_window);
- return false;
- }
+ int i;
- for (i = 0; i < (int)numChanges; ++i) {
- //TODO: change the TYPES of HWCWindows
- }
+ changed_thwc_window = (tdm_hwc_window **)calloc(numChanges, sizeof(tdm_hwc_window *));
+ if (changed_thwc_window == nullptr) {
+ DSLOG_ERR("TDM_HWC", "calloc changed_thwc_window fails.");
+ return false;
+ }
- // TODO: accept_validation is depending on the transitions.
- terror = tdm_hwc_accept_validation(__thwc);
- if (terror != TDM_ERROR_NONE) {
- DSLOG_ERR("TDM_HWC", "tdm_hwc_accept_validation fails.");
- free(tcomposition_types);
- free(changed_thwc_window);
- return false;
- }
+ // get changed_types
+ tcomposition_types = (tdm_hwc_window_composition *)calloc(numChanges, sizeof(tdm_hwc_window_composition));
+ if (tcomposition_types == nullptr) {
+ DSLOG_ERR("TDM_HWC", "calloc changed_thwc_window fails.");
+ free(changed_thwc_window);
+ return false;
+ }
+ terror = tdm_hwc_get_changed_composition_types(__thwc, &numChanges, changed_thwc_window, tcomposition_types);
+ if (terror != TDM_ERROR_NONE) {
+ DSLOG_ERR("TDM_HWC", "tdm_hwc_get_changed_composition_types fails.");
free(tcomposition_types);
free(changed_thwc_window);
+ return false;
}
- //TODO: tdm_hwc_commit
- terror = tdm_hwc_commit(__thwc, 0, NULL, NULL);
+ for (i = 0; i < (int)numChanges; ++i) {
+ //TODO: change the TYPES of HWCWindows
+ }
+
+ free(tcomposition_types);
+ free(changed_thwc_window);
+
+ return true;
+}
+
+bool DSDisplayDeviceHWCTDMImpl::__acceptValidation()
+{
+ tdm_error terror;
+
+ // TODO: accept_validation is depending on the transitions.
+ terror = tdm_hwc_accept_validation(__thwc);
if (terror != TDM_ERROR_NONE) {
- DSLOG_ERR("TDM_HWC", "tdm_hwc_commit fails.");
+ DSLOG_ERR("TDM_HWC", "tdm_hwc_accept_validation fails.\n");
return false;
}
return true;
}
-}
\ No newline at end of file
+
+}
// DSDisplayDeviceTDMHWC
-TEST_F(DSDisplayDeviceTDMImplTest, DeviceOutput_createHWCWindow)
+TEST_F(DSDisplayDeviceTDMImplTest, DeviceOutput_makeHWCWindow)
{
std::unique_ptr<IDSDisplayDevice> displayDevice = std::make_unique<DSDisplayDeviceTDMImpl>();
std::list<std::shared_ptr<IDSDisplayDeviceOutput>> outputList = displayDevice->getOutputList();
IDSDisplayDeviceOutput::ConnectorType connType;
IDSDisplayDeviceOutput::ConnectState connState;
std::shared_ptr<IDSDisplayDeviceHWC> deviceHWC;
- IDSDisplayDeviceHWCWindow *deviceHWCWindow;
+ std::shared_ptr<IDSDisplayDeviceHWCWindow> deviceHWCWindow;
for (std::shared_ptr<IDSDisplayDeviceOutput> output : outputList) {
connType = output->getConnectType();
deviceHWC = output->getHWC();
EXPECT_TRUE(deviceHWC != nullptr);
- deviceHWCWindow = deviceHWC->createHWCWindow();
+ deviceHWCWindow = deviceHWC->makeHWCWindow();
EXPECT_TRUE(deviceHWC != nullptr);
-
- deviceHWC->destroyHWCWindow(deviceHWCWindow);
}
}
IDSDisplayDeviceOutput::ConnectorType connType;
IDSDisplayDeviceOutput::ConnectState connState;
std::shared_ptr<IDSDisplayDeviceHWC> deviceHWC;
- IDSDisplayDeviceHWCWindow *deviceHWCWindow;
+ std::shared_ptr<IDSDisplayDeviceHWCWindow> deviceHWCWindow;
for (std::shared_ptr<IDSDisplayDeviceOutput> output : outputList) {
connType = output->getConnectType();
EXPECT_TRUE(connState <= IDSDisplayDeviceOutput::STATE_MODESET);
if (connState == IDSDisplayDeviceOutput::STATE_DISCONNECTED) continue;
+ DSDisplayDeviceOutputMode *bestMode = nullptr;
+ for (DSDisplayDeviceOutputMode *mode : output->getAvailableModes()) {
+ if (bestMode == nullptr) {
+ bestMode = mode;
+ continue;
+ }
+
+ int resSize = mode->hdisplay * mode->vdisplay;
+ int resSizeBest = bestMode->hdisplay *bestMode->vdisplay;
+ if (resSize > resSizeBest) {
+ bestMode = mode;
+ }
+ }
+ EXPECT_TRUE(output->setMode(bestMode) == true);
+ EXPECT_TRUE(output->getMode() == bestMode);
+
deviceHWC = output->getHWC();
EXPECT_TRUE(deviceHWC != nullptr);
- deviceHWCWindow = deviceHWC->createHWCWindow();
+ auto bufferQueue = deviceHWC->getTargetBufferQueue();
EXPECT_TRUE(deviceHWC != nullptr);
- // commit
- deviceHWC->commit();
+ deviceHWCWindow = deviceHWC->makeHWCWindow();
+ EXPECT_TRUE(deviceHWC != nullptr);
+ EXPECT_TRUE(deviceHWC->addVisibleHWCWindow(deviceHWCWindow));
+
+ auto buffer = bufferQueue->dequeueBuffer();
+ EXPECT_TRUE(buffer != nullptr);
- deviceHWC->destroyHWCWindow(deviceHWCWindow);
+ EXPECT_TRUE(deviceHWC->setTargetBuffer(buffer));
+
+ // commit
+ EXPECT_TRUE(deviceHWC->commit());
}
}
\ No newline at end of file