Merge "hwc: always_split: Use pipe clock comparison to mixer to split"
diff --git a/Android.mk b/Android.mk
index d8b168d..4a951c8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,6 +1,16 @@
-display-hals := libgralloc libgenlock libcopybit liblight
-display-hals += libhwcomposer liboverlay libqdutils libhdmi libqservice
-display-hals += libmemtrack
+# This flag will be set to true during migration to Snapdragon Display Engine.
+TARGET_USES_SDE = false
+
+display-hals := libgralloc libcopybit liblight libmemtrack
+
+ifeq ($(TARGET_USES_SDE), true)
+ sde-libs := displayengine/libs
+ display-hals += $(sde-libs)/utils $(sde-libs)/core $(sde-libs)/hwc
+else
+ display-hals += libgenlock libhwcomposer liboverlay libqdutils libhdmi
+ display-hals += libqservice
+endif
+
ifeq ($(call is-vendor-board-platform,QCOM),true)
include $(call all-named-subdir-makefiles,$(display-hals))
else
diff --git a/displayengine/include/core/core_interface.h b/displayengine/include/core/core_interface.h
new file mode 100644
index 0000000..3328d64
--- /dev/null
+++ b/displayengine/include/core/core_interface.h
@@ -0,0 +1,183 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file core_interface.h
+ @brief Interface file for core of the display subsystem.
+
+ @details Display core is primarily used for loading and unloading different display device
+ components viz primary, external and virtual. Display core is a statically linked library which
+ runs in caller's process context.
+*/
+#ifndef __CORE_INTERFACE_H__
+#define __CORE_INTERFACE_H__
+
+#include <stdint.h>
+
+#include "device_interface.h"
+#include "display_types.h"
+
+/*! @brief Display core interface version.
+
+ @details Display core interfaces are version tagged to maintain backward compatibility. This
+ version is supplied as a default argument during display core initialization.
+
+ Client may use an older version of interfaces and link to a higher version of display core
+ library, but vice versa is not allowed.
+
+ A 32-bit client must use 32-bit display core library and a 64-bit client must use 64-bit display
+ core library.
+
+ Display core interfaces follow default data structures alignment. Client must not override the
+ default padding rules while using these interfaces.
+
+ @warning It is assumed that client upgrades or downgrades display core interface all at once
+ and recompile all binaries which use these interfaces. Mix and match of these interfaces can
+ lead to unpredictable behaviour.
+
+ @sa CoreInterface::CreateCore
+*/
+#define CORE_REVISION_MAJOR (1)
+#define CORE_REVISION_MINOR (0)
+
+#define CORE_VERSION_TAG ((uint32_t) ((CORE_REVISION_MAJOR << 24) | (CORE_REVISION_MINOR << 16) \
+ | (sizeof(DisplayCompatibility) << 8) | sizeof(int *)))
+
+namespace sde {
+
+/*! @brief Event data associated with hotplug event.
+
+ @sa CoreEventHandler::Hotplug
+*/
+struct CoreEventHotplug {
+ bool connected; //!< True when device is connected.
+
+ CoreEventHotplug() : connected(false) { }
+};
+
+/*! @brief Display core event handler implemented by the client.
+
+ @details This class declares prototype for display core event handler methods which must be
+ implemented by the client. Display core will use these methods to notify events to the client.
+ Client must post heavy-weight event handling to a separate thread and unblock display core thread
+ instantly.
+
+ @sa CoreInterface::CreateCore
+*/
+class CoreEventHandler {
+ public:
+ /*! @brief Event handler for Hotplug event.
+
+ @details Event generated when a display device is connected or disconnected. Applicable to
+ detachable displays only.
+
+ @param[in] \link CoreEventHotplug \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError Hotplug(const CoreEventHotplug &hotplug) = 0;
+
+ protected:
+ virtual ~CoreEventHandler() { }
+};
+
+/*! @brief Display core interface.
+
+ @details This class defines display core interfaces. It contains methods which client shall use
+ to create/destroy different display devices. This interface is created during display core
+ CreateCore() and remains valid until DestroyCore().
+
+ @sa CoreInterface::CreateCore
+ @sa CoreInterface::DestroyCore
+*/
+class CoreInterface {
+ public:
+ /*! @brief Method to create and get handle to display core interface.
+
+ @details This method is the entry point into the display core. Client can create and operate on
+ different display devices only through a valid interface handle obtained using this method. An
+ object of display core is created and handle to this object is returned via output parameter.
+ This interface shall be called only once.
+
+ @param[in] event_handler \link CoreEventHandler \endlink
+ @param[out] interface \link CoreInterface \endlink
+ @param[in] version \link CORE_VERSION_TAG \endlink. Client must not override this argument.
+
+ @return \link DisplayError \endlink
+
+ @sa DestroyCore
+ */
+ static DisplayError CreateCore(CoreEventHandler *event_handler, CoreInterface **interface,
+ uint32_t version = CORE_VERSION_TAG);
+
+ /*! @brief Method to release handle to display core interface.
+
+ @details The object of corresponding display core is destroyed when this method is invoked.
+ Client must explicitly destroy all created display device objects associated with this handle
+ before invoking this method.
+
+ @param[in] interface \link CoreInterface \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa CreateCore
+ */
+ static DisplayError DestroyCore();
+
+ /*! @brief Method to create a display device for a given type.
+
+ @details Client shall use this method to create each of the connected display type. A handle to
+ interface associated with this object is returned via output parameter which can be used to
+ interact further with the display device.
+
+ @param[in] type \link DeviceType \endlink
+ @param[in] event_handler \link DeviceEventHandler \endlink
+ @param[out] interface \link DisplayInterface \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa DestroyDevice
+ */
+ virtual DisplayError CreateDevice(DeviceType type, DeviceEventHandler *event_handler,
+ DeviceInterface **interface) = 0;
+
+ /*! @brief Method to destroy a display device.
+
+ @details Client shall use this method to destroy each of the created display device objects.
+
+ @param[in] interface \link DisplayInterface \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa CreateDevice
+ */
+ virtual DisplayError DestroyDevice(DeviceInterface *interface) = 0;
+
+ protected:
+ virtual ~CoreInterface() { }
+};
+
+} // namespace sde
+
+#endif // __CORE_INTERFACE_H__
+
diff --git a/displayengine/include/core/device_interface.h b/displayengine/include/core/device_interface.h
new file mode 100644
index 0000000..01c5446
--- /dev/null
+++ b/displayengine/include/core/device_interface.h
@@ -0,0 +1,286 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file device_interface.h
+ @brief Interface file for display device which represents a physical panel or an output buffer
+ where contents can be rendered.
+
+ @details Display device is used to send layer buffers for composition and get them rendered onto
+ the target device. Each display device represents a unique display target which may be either a
+ physical panel or an output buffer..
+*/
+#ifndef __DEVICE_INTERFACE_H__
+#define __DEVICE_INTERFACE_H__
+
+#include <stdint.h>
+
+#include "layer_stack.h"
+#include "display_types.h"
+
+namespace sde {
+
+/*! @brief This enum represents display device types where contents can be rendered.
+
+ @sa CoreInterface::CreateDevice
+ @sa CoreInterface::IsDeviceSupported
+*/
+enum DeviceType {
+ kPrimary, //!< Main physical display which is attached to the handheld device.
+ kHDMI, //!< HDMI physical display which is generally detachable.
+ kVirtual, //!< Contents would be rendered into the output buffer provided by the client
+ //!< e.g. wireless display.
+};
+
+/*! @brief This enum represents states of a display device.
+
+ @sa DisplayInterface::GetDeviceState
+ @sa DisplayInterface::SetDeviceState
+*/
+enum DeviceState {
+ kStateOff, //!< Display is OFF. Contents are not rendered in this state. Client will not
+ //!< receive VSync events in this state. This is default state as well.
+
+ kStateOn, //!< Display is ON. Contents are rendered in this state.
+
+ kStateDoze, //!< Display is ON but not updating contents. Client shall not push any contents
+ //!< in this state.
+
+ kStateStandby, //!< Display is OFF. Client will continue to receive VSync events in this state
+ //!< if VSync is enabled. Contents are not rendered in this state.
+};
+
+/*! @brief This structure defines configuration for fixed properties of a display device.
+
+ @sa DisplayInterface::GetConfig
+ @sa DisplayInterface::SetConfig
+*/
+struct DeviceConfigFixedInfo {
+ bool underscan; //!< If display support CE underscan.
+ bool secure; //!< If this display is capable of handling secure content.
+
+ DeviceConfigFixedInfo() : underscan(false), secure(false) { }
+};
+
+/*! @brief This structure defines configuration for variable properties of a display device.
+
+ @sa DisplayInterface::GetConfig
+ @sa DisplayInterface::SetConfig
+*/
+struct DeviceConfigVariableInfo {
+ uint32_t x_pixels; //!< Total number of pixels in X-direction on the display panel.
+ uint32_t y_pixels; //!< Total number of pixels in Y-direction on the display panel.
+ float x_dpi; //!< Dots per inch in X-direction.
+ float y_dpi; //!< Dots per inch in Y-direction.
+ float fps; //!< Frame rate per second.
+ uint32_t vsync_period_ns; //!< VSync period in nanoseconds.
+
+ DeviceConfigVariableInfo() : x_pixels(0), y_pixels(0), x_dpi(0.0f), y_dpi(0.0f),
+ fps(0.0f), vsync_period_ns(0) { }
+};
+
+/*! @brief Event data associated with VSync event.
+
+ @sa DeviceEventHandler::VSync
+*/
+struct DeviceEventVSync {
+ int64_t timestamp; //!< System monotonic clock timestamp in nanoseconds.
+
+ DeviceEventVSync() : timestamp(0) { }
+};
+
+/*! @brief Display device event handler implemented by the client.
+
+ @details This class declares prototype for display device event handler methods which must be
+ implemented by the client. Display device will use these methods to notify events to the client.
+ Client must post heavy-weight event handling to a separate thread and unblock display engine
+ thread instantly.
+
+ @sa CoreInterface::CreateDevice
+*/
+class DeviceEventHandler {
+ public:
+ /*! @brief Event handler for VSync event.
+
+ @details This event is dispatched on every vertical synchronization. The event is disabled by
+ default.
+
+ @param[in] vsync \link DeviceEventVSync \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa DeviceInterface::GetDeviceState
+ @sa DeviceInterface::SetDeviceState
+ */
+ virtual DisplayError VSync(const DeviceEventVSync &vsync) = 0;
+
+ /*! @brief Event handler for Refresh event.
+
+ @details This event is dispatched to trigger a screen refresh. Client must call Prepare() and
+ Commit() in response to it from a separate thread. There is no data associated with this
+ event.
+
+ @return \link DisplayError \endlink
+
+ @sa DeviceInterface::Prepare
+ @sa DeviceInterface::Commit
+ */
+ virtual DisplayError Refresh() = 0;
+
+ protected:
+ virtual ~DeviceEventHandler() { }
+};
+
+/*! @brief Display device interface.
+
+ @details This class defines display device interface. It contains methods which client shall use
+ to configure or submit layers for composition on the display device. This interface is created
+ during display device creation and remains valid until destroyed.
+
+ @sa CoreInterface::CreateDevice
+ @sa CoreInterface::DestroyDevice
+*/
+class DeviceInterface {
+ public:
+ /*! @brief Method to determine hardware capability to compose layers associated with given frame.
+
+ @details Client shall send all layers associated with a frame targeted for current display
+ using this method and check the layers which can be handled completely in display engine.
+
+ Client shall mark composition type for one of the layer as kCompositionGPUTarget; the GPU
+ composed output would be rendered at the specified layer if some of the layers are not handled
+ by SDE.
+
+ Display engine will set each layer as kCompositionGPU or kCompositionSDE upon return. Client
+ shall render all the layers marked as kCompositionGPU using GPU.
+
+ This method can be called multiple times but only last call prevails. This method must be
+ followed by Commit().
+
+ @param[inout] layer_stack \link LayerStack \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa Commit
+ */
+ virtual DisplayError Prepare(LayerStack *layer_stack) = 0;
+
+ /*! @brief Method to commit layers of a frame submitted in a former call to Prepare().
+
+ @details Client shall call this method to submit layers for final composition. The composed
+ output would be displayed on the panel or written in output buffer.
+
+ Client must ensure that layer stack is same as previous call to Prepare.
+
+ This method shall be called only once for each frame.
+
+ In the event of an error as well, this call will cause any fences returned in the previous call
+ to Commit() to eventually become signaled, so the client's wait on fences can be released to
+ prevent deadlocks.
+
+ @param[in] layer_stack \link LayerStack \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa Prepare
+ */
+ virtual DisplayError Commit(LayerStack *layer_stack) = 0;
+
+ /*! @brief Method to get current state of the display device.
+
+ @param[out] state \link DisplayState \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa SetDeviceState
+ */
+ virtual DisplayError GetDeviceState(DeviceState *state) = 0;
+
+ /*! @brief Method to get number of configurations(variable properties) supported on the display
+ device.
+
+ @param[out] count Number of modes supported; mode index starts with 0.
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count) = 0;
+
+ /*! @brief Method to get configuration for fixed properties of the display device.
+
+ @param[out] fixed_info \link DeviceConfigFixedInfo \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetConfig(DeviceConfigFixedInfo *fixed_info) = 0;
+
+ /*! @brief Method to get configuration for variable properties of the display device.
+
+ @param[in] mode index of the mode
+ @param[out] variable_info \link DeviceConfigVariableInfo \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetConfig(DeviceConfigVariableInfo *variable_info, uint32_t mode) = 0;
+
+ /*! @brief Method to get VSync event state. Default event state is disabled.
+
+ @param[out] enabled vsync state
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetVSyncState(bool *enabled) = 0;
+
+ /*! @brief Method to set current state of the display device.
+
+ @param[in] state \link DisplayState \endlink
+
+ @return \link DisplayError \endlink
+
+ @sa SetDeviceState
+ */
+ virtual DisplayError SetDeviceState(DeviceState state) = 0;
+
+ /*! @brief Method to set configuration for variable properties of the display device.
+
+ @param[in] mode index of the mode corresponding to variable properties.
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetConfig(uint32_t mode) = 0;
+
+ /*! @brief Method to set VSync event state. Default event state is disabled.
+
+ @param[out] enabled vsync state
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetVSyncState(bool enable) = 0;
+
+ protected:
+ virtual ~DeviceInterface() { }
+};
+
+} // namespace sde
+
+#endif // __DEVICE_INTERFACE_H__
+
diff --git a/displayengine/include/core/display_types.h b/displayengine/include/core/display_types.h
new file mode 100644
index 0000000..128e7d9
--- /dev/null
+++ b/displayengine/include/core/display_types.h
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file display_types.h
+ @brief This file contains miscellaneous data types used across display interfaces.
+*/
+#ifndef __DISPLAY_TYPES_H__
+#define __DISPLAY_TYPES_H__
+
+namespace sde {
+
+/*! @brief This enum represents different error codes that display interfaces may return.
+*/
+enum DisplayError {
+ kErrorNone = 0, //!< Call executed successfully.
+ kErrorUndefined, //!< An unspecified error has occured.
+ kErrorNotSupported, //!< Requested operation is not supported.
+ kErrorVersion, //!< Client is using advanced version of interfaces and calling into an
+ //!< older version of display library.
+ kErrorDataAlignment, //!< Client data structures are not aligned on naturual boundaries.
+ kErrorInstructionSet, //!< 32-bit client is calling into 64-bit library or vice versa.
+ kErrorParameters, //!< Invalid parameters passed to a method.
+ kErrorFileDescriptor, //!< Invalid file descriptor.
+ kErrorMemory, //!< System is running low on memory.
+ kErrorResources, //!< Not enough hardware resources available to execute call.
+ kErrorHardware, //!< A hardware error has occured.
+ kErrorTimeOut, //!< The operation has timed out to prevent client from waiting forever.
+};
+
+/*! @brief This structure is defined for client and library compatibility check purpose only. This
+ structure is used in CORE_VERSION_TAG definition only. Client should not refer it directly for
+ any purpose.
+*/
+struct DisplayCompatibility {
+ char c1;
+ int i1;
+ char c2;
+ int i2;
+};
+
+} // namespace sde
+
+#endif // __DISPLAY_TYPES_H__
+
diff --git a/displayengine/include/core/dump_interface.h b/displayengine/include/core/dump_interface.h
new file mode 100644
index 0000000..674e60f
--- /dev/null
+++ b/displayengine/include/core/dump_interface.h
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file dump_interface.h
+ @brief Interface file for dump options provided by display engine.
+
+*/
+#ifndef __DUMP_INTERFACE_H__
+#define __DUMP_INTERFACE_H__
+
+#include <stdint.h>
+
+#include "display_types.h"
+
+namespace sde {
+
+/*! @brief Display dump interface.
+
+ @details This class defines dump methods provided by display engine.
+
+*/
+class DumpInterface {
+ public:
+ /*! @brief Method to get dump information in form of a string.
+
+ @details Client shall use this method to get current snapshot of display engine context as a
+ formatted string for logging or dumping purposes.
+
+ @param[inout] buffer String buffer allocated by the client. Filled with dump information upon
+ return.
+ @param[in] length Length of the string buffer. Length shall be offset adjusted if any.
+ @param[in] filled Number of bytes filled into the string buffer.
+
+ @return \link DisplayError \endlink
+
+ @warning Client shall ensure that this interface is not used while a device is being either
+ created or destroyed through display core.
+ */
+ static DisplayError GetDump(uint8_t *buffer, uint32_t length, uint32_t *filled);
+
+ protected:
+ virtual ~DumpInterface() { }
+};
+
+} // namespace sde
+
+#endif // __DUMP_INTERFACE_H__
+
diff --git a/displayengine/include/core/layer_buffer.h b/displayengine/include/core/layer_buffer.h
new file mode 100644
index 0000000..e6dcf1c
--- /dev/null
+++ b/displayengine/include/core/layer_buffer.h
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file layer_buffer.h
+ @brief File for layer buffer structure.
+
+*/
+#ifndef __LAYER_BUFFER_H__
+#define __LAYER_BUFFER_H__
+
+#include <stdint.h>
+
+#include "display_types.h"
+
+namespace sde {
+
+/*! @brief This enum represents different buffer formats supported by display engine.
+
+ @sa LayerBuffer
+*/
+enum LayerBufferFormat {
+ /* All RGB formats, Any new format will be added towards end of this group to maintain backward
+ compatibility.
+ */
+ kFormatARGB8888, //!< 8-bits Alpha, Red, Green, Blue interleaved in ARGB order.
+ kFormatRGBA8888, //!< 8-bits Red, Green, Blue, Alpha interleaved in RGBA order.
+ kFormatBGRA8888, //!< 8-bits Blue, Green, Red, Alpha interleaved in BGRA order.
+ kFormatXRGB8888, //!< 8-bits Padding, Red, Green, Blue interleaved in XRGB order. No Alpha.
+ kFormatRGBX8888, //!< 8-bits Red, Green, Blue, Padding interleaved in RGBX order. No Alpha.
+ kFormatBGRX8888, //!< 8-bits Blue, Green, Red, Padding interleaved in BGRX order. No Alpha.
+ kFormatRGB888, //!< 8-bits Red, Green, Blue interleaved in RGB order. No Alpha.
+ kFormatRGB565, //!< 5-bit Red, 6-bit Green, 5-bit Blue interleaved in RGB order. No Alpha.
+
+ /* All YUV-Planar formats, Any new format will be added towards end of this group to maintain
+ backward compatibility.
+ */
+ kFormatYCbCr420Planar = 0x100, //!< Y-plane: y(0), y(1), y(2) ... y(n)
+ //!< 2x2 subsampled U-plane: u(0), u(2) ... u(n-1)
+ //!< 2x2 subsampled V-plane: v(0), v(2) ... v(n-1)
+
+ kFormatYCrCb420Planar, //!< Y-plane: y(0), y(1), y(2) ... y(n)
+ //!< 2x2 subsampled V-plane: v(0), v(2) ... v(n-1)
+ //!< 2x2 subsampled U-plane: u(0), u(2) ... u(n-1)
+
+ /* All YUV-Semiplanar formats, Any new format will be added towards end of this group to
+ maintain backward compatibility.
+ */
+ kFormatYCbCr420SemiPlanar = 0x200, //!< Y-plane: y(0), y(1), y(2) ... y(n)
+ //!< 2x2 subsampled interleaved UV-plane:
+ //!< u(0), v(0), u(2), v(2) ... u(n-1), v(n-1)
+ //!< aka NV12.
+
+ kFormatYCrCb420SemiPlanar, //!< Y-plane: y(0), y(1), y(2) ... y(n)
+ //!< 2x2 subsampled interleaved VU-plane:
+ //!< v(0), u(0), v(2), u(2) ... v(n-1), u(n-1)
+ //!< aka NV21.
+
+ /* All YUV-Packed formats, Any new format will be added towards end of this group to maintain
+ backward compatibility.
+ */
+ kFormatYCbCr422Packed = 0x300, //!< Y-plane interleaved with horizontally subsampled U/V by
+ //!< factor of 2
+ //!< u(0), y(0), v(0), y(1), u(2), y(2), v(2), y(3)
+ //!< u(n-1), y(n-1), v(n-1), y(n)
+};
+
+/*! @brief This structure defines a color sample plane belonging to a buffer format. RGB buffer
+ formats have 1 plane whereas YUV buffer formats may have upto 4 planes.
+
+ @sa LayerBuffer
+*/
+struct LayerBufferPlane {
+ int fd; //!< File descriptor referring to the buffer associated with this plane.
+ uint32_t offset; //!< Offset of the plane in bytes from beginning of the buffer.
+ uint32_t stride; //!< Stride in bytes i.e. length of a scanline including padding.
+
+ LayerBufferPlane() : fd(-1), offset(0), stride(0) { }
+};
+
+/*! @brief This structure defines flags associated with a layer buffer. The 1-bit flag can be set
+ to ON(1) or OFF(0).
+
+ @sa LayerBuffer
+*/
+struct LayerBufferFlags {
+ uint64_t secure : 1; //!< This flag shall be set by client to indicate that the buffer need
+ //!< to be handled securely.
+
+ LayerBufferFlags() : secure(0) { }
+};
+
+/*! @brief This structure defines a layer buffer handle which contains raw buffer and its associated
+ properties.
+
+ @sa LayerBuffer
+ @sa LayerStack
+*/
+struct LayerBuffer {
+ uint32_t width; //!< Actual width of the Layer that this buffer is for.
+ uint32_t height; //!< Actual height of the Layer that this buffer is for.
+ LayerBufferFormat format; //!< Format of the buffer content.
+ LayerBufferPlane planes[4]; //!< Array of planes that this buffer contains. RGB buffer formats
+ //!< have 1 plane whereas YUV buffer formats may have upto 4 planes.
+ //!< Total number of planes for the buffer will be interpreted based
+ //!< on the buffer format specified.
+
+ int acquire_fence_fd; //!< File descriptor referring to a sync fence object which will be
+ //!< signaled when buffer can be read/write by display engine.
+ //!< This fence object is set by the client during Commit(). For
+ //!< input buffers client shall signal this fence when buffer
+ //!< content is available and can be read by display engine. For
+ //!< output buffers, client shall signal fence when buffer is ready
+ //!< to be written by display engine.
+
+ //!< This field is used only during Commit() and shall be set to -1
+ //!< by the client when buffer is already available for read/write.
+
+ int release_fence_fd; //!< File descriptor referring to a sync fence object which will be
+ //!< signaled when buffer has been read/written by display engine.
+ //!< This fence object is set by display engine during Commit().
+ //!< For input buffers display engine will signal this fence when
+ //!< buffer has been consumed. For output buffers, display engine
+ //!< will signal this fence when buffer is produced.
+
+ //!< This field is used only during Commit() and will be set to -1
+ //!< by display engine when buffer is already available for
+ //!< read/write.
+
+ LayerBufferFlags flags; //!< Flags associated with this buffer.
+
+ LayerBuffer() : width(0), height(0), format(kFormatRGBA8888), acquire_fence_fd(-1),
+ release_fence_fd(-1) { }
+};
+
+} // namespace sde
+
+#endif // __LAYER_BUFFER_H__
+
diff --git a/displayengine/include/core/layer_stack.h b/displayengine/include/core/layer_stack.h
new file mode 100644
index 0000000..fddfa8e
--- /dev/null
+++ b/displayengine/include/core/layer_stack.h
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file layer_stack.h
+ @brief File for display layer stack structure which represents a drawing buffer.
+
+ @details Display layer is a drawing buffer object which will be blended with other drawing buffers
+ under blending rules.
+*/
+#ifndef __LAYER_STACK_H__
+#define __LAYER_STACK_H__
+
+#include <stdint.h>
+
+#include "layer_buffer.h"
+#include "display_types.h"
+
+namespace sde {
+
+/*! @brief This enum represents display layer blending types.
+
+ @sa Layer
+*/
+enum LayerBlending {
+ kBlendingNone = 0, //!< Blend operation is not specified.
+
+ kBlendingOpaque, //!< Pixel color is expressed using straight alpha in color tuples. It
+ //!< is constant blend operation. The layer would appear opaque if plane
+ //!< alpha is 0xFF.
+
+ kBlendingPremultiplied, //!< Pixel color is expressed using premultiplied alpha in RGBA tuples.
+ //!< If plane alpha is less than 0xFF, apply modulation as well.
+ //!< pixel.rgb = src.rgb + dest.rgb x (1 - src.a)
+
+ kBlendingCoverage, //!< Pixel color is expressed using straight alpha in color tuples. If
+ //!< plane alpha is less than 0xff, apply modulation as well.
+ //!< pixel.rgb = src.rgb x src.a + dest.rgb x (1 - src.a)
+};
+
+/*! @brief This enum represents display layer composition types.
+
+ @sa Layer
+*/
+enum LayerComposition {
+ kCompositionGPU, //!< This layer will be drawn into the target buffer by GPU. Display
+ //!< device will mark the layer for SDE composition if it can handle it
+ //!< or it will mark the layer for GPU composition.
+
+ kCompositionSDE, //!< This layer will be handled by SDE. It must not be composed by GPU.
+
+ kCompositionGPUTarget, //!< This layer will hold result of composition for layers marked for GPU
+ //!< composition. If display device sets all other layers for SDE
+ //!< composition then this layer would be ignored during Commit().
+ //!< Only one layer shall be marked as target buffer by the caller.
+};
+
+/*! @brief This structure defines rotation and flip values for a display layer.
+
+ @sa Layer
+*/
+struct LayerTransform {
+ float rotation; //!< Left most pixel coordinate.
+ bool flip_horizontal; //!< Mirror reversal of the layer across a horizontal axis.
+ bool flip_vertical; //!< Mirror reversal of the layer across a vertical axis.
+
+ LayerTransform() : rotation(0.0f), flip_horizontal(false), flip_vertical(false) { }
+};
+
+/*! @brief This structure defines flags associated with a layer. The 1-bit flag can be set to ON(1)
+ or OFF(0).
+
+ @sa LayerBuffer
+*/
+struct LayerFlags {
+ uint64_t skip : 1; //!< This flag shall be set by client to indicate that this layer will be
+ //!< handled by GPU. Device Device will not consider it for composition.
+
+ LayerFlags() : skip(0) { }
+};
+
+/*! @brief This structure defines flags associated with a layer stack. The 1-bit flag can be set to
+ ON(1) or OFF(0).
+
+ @sa LayerBuffer
+*/
+struct LayerStackFlags {
+ uint64_t geometry_changed : 1; //!< This flag shall be set by client to indicate that the layer
+ //!< set passed to Prepare() has changed by more than just the
+ //!< buffer handles and acquire fences.
+
+ LayerStackFlags() : geometry_changed(0) { }
+};
+
+/*! @brief This structure defines a rectanglular area inside a display layer.
+
+ @sa LayerRectArray
+*/
+struct LayerRect {
+ float left; //!< Left-most pixel coordinate.
+ float top; //!< Top-most pixel coordinate.
+ float right; //!< Right-most pixel coordinate.
+ float bottom; //!< Bottom-most pixel coordinate.
+
+ LayerRect() : left(0.0f), top(0.0f), right(0.0f), bottom(0.0f) { }
+};
+
+/*! @brief This structure defines an array of display layer rectangles.
+
+ @sa LayerRect
+*/
+struct LayerRectArray {
+ LayerRect *rect; //!< Pointer to first element of array.
+ uint32_t count; //!< Number of elements in the array.
+
+ LayerRectArray() : rect(NULL), count(0) { }
+};
+
+/*! @brief This structure defines display layer object which contains layer properties and a drawing
+ buffer.
+
+ @sa LayerArray
+*/
+struct Layer {
+ LayerBuffer *input_buffer; //!< Pointer to the buffer to be composed. If this remains
+ //!< unchanged between two consecutive Prepare() calls and
+ //!< geometry_changed flag is not set for the second call, then
+ //!< the display device will assume that buffer content has not
+ //!< changed.
+
+ LayerComposition composition; //!< Composition type which can be set by either the client or
+ //!< the display device. This value should be preserved between
+ //!< Prepare() and Commit() calls.
+
+ LayerRect src_rect; //!< Rectangular area of the layer buffer to consider for
+ //!< composition.
+
+ LayerRect dst_rect; //!< The target position where the frame will be displayed.
+ //!< Cropping rectangle is scaled to fit into this rectangle.
+ //!< The origin is top-left corner of the screen.
+
+ LayerRectArray visible_regions; //!< Visible rectangular areas in screen space. The visible
+ //!< region includes areas overlapped by a translucent layer.
+
+ LayerRectArray dirty_regions; //!< Rectangular areas in the current frames that have changed
+ //!< in comparison to previous frame.
+
+ LayerBlending blending; //!< Blending operation which need to be applied on the layer
+ //!< buffer during composition.
+
+ LayerTransform transform; //!< Rotation/Flip operations which need to be applied to the
+ //!< layer buffer during composition.
+
+ uint8_t plane_alpha; //!< Alpha value applied to the whole layer. Value of each pixel
+ //!< computed as:
+ //!< if(kBlendingPremultiplied) {
+ //!< pixel.RGB = pixel.RGB * planeAlpha / 255
+ //!< }
+ //!< pixel.a = pixel.a * planeAlpha
+
+ LayerFlags flags; //!< Flags associated with this layer.
+
+ Layer() : input_buffer(NULL), composition(kCompositionGPU), blending(kBlendingNone),
+ plane_alpha(0) { }
+};
+
+/*! @brief This structure defines a layer stack that contains layers which need to be composed and
+ rendered onto the target.
+
+ @sa DisplayInterface::Prepare
+ @sa DisplayInterface::Commit
+*/
+struct LayerStack {
+ union {
+ int retire_fence_fd; //!< File descriptor referring to a sync fence object which will
+ //!< be signaled when this composited frame has been replaced on
+ //!< screen by a subsequent frame on a physical display. The fence
+ //!< object is created and returned during Commit(). Client shall
+ //!< Client shall close the returned file descriptor.
+ //!< NOTE: This field applies to a physical display only.
+
+ LayerBuffer *output_buffer; //!< Pointer to the buffer where composed buffer would be rendered
+ //!< for virtual displays.
+ //!< NOTE: This field applies to a virtual display only.
+ };
+
+ Layer *layers; //!< Array of layers.
+ uint32_t layer_count; //!< Total number of layers.
+ LayerStackFlags flags; //!< Flags associated with this layer set.
+
+ LayerStack() : output_buffer(NULL) { }
+};
+
+} // namespace sde
+
+#endif // __LAYER_STACK_H__
+
diff --git a/displayengine/include/private/strategy_interface.h b/displayengine/include/private/strategy_interface.h
new file mode 100644
index 0000000..7050929
--- /dev/null
+++ b/displayengine/include/private/strategy_interface.h
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! @file strategy_interface.h
+ @brief Interface file for strategy manager which will be used by display core to select a
+ composition strategy for a frame to be displayed on target.
+*/
+#ifndef __STRATEGY_INTERFACE_H__
+#define __STRATEGY_INTERFACE_H__
+
+#include <core/display_types.h>
+
+namespace sde {
+
+/*! @brief Strategy library name
+
+ @details This macro defines name for the composition strategy library. This macro shall be used
+ to load library using dlopen().
+
+ @sa GetStrategyInterface
+*/
+#define STRATEGY_LIBRARY_NAME "libsdestrategy.so"
+
+/*! @brief Function name to get composer strategy interface
+
+ @details This macro defines function name for GetStrategyInterface() which will be implemented
+ in the composition strategy library. This macro shall be used to specify name of the function
+ in dlsym().
+
+ @sa GetStrategyInterface
+*/
+#define GET_STRATEGY_INTERFACE_NAME "GetStrategyInterface"
+
+class StrategyInterface;
+
+/*! @brief Function to get composer strategy interface.
+
+ @details This function is used to get StrategyInterface object which resides in the composer
+ strategy library loaded at runtime.
+
+ @param[out] interface \link StrategyInterface \endlink
+
+ @return \link DisplayError \endlink
+*/
+typedef DisplayError (*GetStrategyInterface)(StrategyInterface **interface);
+
+/*! @brief Maximum number of layers that can be handled by hardware in a given layer stack.
+*/
+const int kNumLayersMax = 16;
+
+/*! @brief This structure defines constraints and device properties that shall be considered for
+ deciding a composition strategy.
+
+ @sa GetNextStrategy
+*/
+struct StrategyConstraints {
+ bool gpu_only; //!< Select GPU only composition for this layer stack.
+ uint32_t max_layers; //!< Maximum number of layers that shall be programmed on hardware for the
+ //!< given layer stack.
+
+ StrategyConstraints() : gpu_only(false), max_layers(kNumLayersMax) { }
+};
+
+/*! @brief Flag to denote that GPU composition is performed for the given layer stack.
+*/
+const uint32_t kFlagGPU = 0x1;
+
+/*! @brief This structure encapsulates information about the input layer stack and the layers which
+ shall be programmed on hardware.
+
+ @sa GetNextStrategy
+*/
+struct HWLayersInfo {
+ LayerStack *stack; //!< Input layer stack. Set by the caller.
+
+ uint32_t index[kNumLayersMax];
+ //!< Indexes of the layers from the layer stack which need to be
+ //!< programmed on hardware.
+ uint32_t count; //!< Total number of layers which need to be set on hardware.
+ uint32_t flags; //!< Strategy flags. There is one flag set for each of the strategy
+ //!< that has been selected for this layer stack. This flag is preserved
+ //!< between multiple GetNextStrategy() calls. Composition manager
+ //!< relies on the total flag count to check the number of strategies
+ //!< that are attempted for this layer stack.
+
+ HWLayersInfo() {
+ Reset();
+ }
+
+ void Reset() {
+ stack = NULL;
+ count = 0;
+ flags = 0;
+ }
+};
+
+class StrategyInterface {
+ public:
+ /*! @brief Method to get strategy for a layer stack. Caller can loop through this method to try
+ get all applicable strategies.
+
+ @param[in] constraints \link StrategyConstraints \endlink
+ @param[inout] layers_info \link HWLayersInfo \endlink
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetNextStrategy(StrategyConstraints *constraints,
+ HWLayersInfo *hw_layers_info) = 0;
+
+ protected:
+ virtual ~StrategyInterface() { }
+};
+
+} // namespace sde
+
+#endif // __STRATEGY_INTERFACE_H__
+
diff --git a/displayengine/include/utils/constants.h b/displayengine/include/utils/constants.h
new file mode 100644
index 0000000..4b18ed6
--- /dev/null
+++ b/displayengine/include/utils/constants.h
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __CONSTANTS_H__
+#define __CONSTANTS_H__
+
+#define LIKELY(exp) __builtin_expect((exp) != 0, true)
+#define UNLIKELY(exp) __builtin_expect((exp) != 0, false)
+
+#define INT(exp) static_cast<int>(exp)
+#define FLOAT(exp) static_cast<float>(exp)
+#define UINT32(exp) static_cast<uint32_t>(exp)
+#define INT32(exp) static_cast<int32_t>(exp)
+
+#define STRUCT_VAR(struct_name, var_name) \
+ struct struct_name var_name; \
+ memset(&var_name, 0, sizeof(var_name));
+
+#define STRUCT_VAR_ARRAY(struct_name, var_name, num_var) \
+ struct struct_name var_name[num_var]; \
+ memset(&var_name[0], 0, sizeof(var_name));
+
+#define ROUND_UP(number, step) ((((number) + ((step) - 1)) / (step)) * (step))
+
+namespace sde {
+
+ const int kThreadPriorityUrgent = -9;
+
+ typedef void * Handle;
+
+} // namespace sde
+
+#endif // __CONSTANTS_H__
+
diff --git a/displayengine/include/utils/debug.h b/displayengine/include/utils/debug.h
new file mode 100644
index 0000000..10d5ea6
--- /dev/null
+++ b/displayengine/include/utils/debug.h
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#ifndef SDE_LOG_TAG
+#define SDE_LOG_TAG kLogTagNone
+#endif
+
+#ifndef SDE_MODULE_NAME
+#define SDE_MODULE_NAME "SDE"
+#endif
+
+#define DLOG(method, format, ...) Debug::method(SDE_LOG_TAG, SDE_MODULE_NAME ": " format, \
+ ##__VA_ARGS__)
+
+// SDE_LOG_TAG and SDE_MODULE_NAME must be defined before #include this header file in
+// respective module, else default definitions are used.
+#define DLOGE(format, ...) DLOG(Error, format, ##__VA_ARGS__)
+#define DLOGW(format, ...) DLOG(Warning, format, ##__VA_ARGS__)
+#define DLOGI(format, ...) DLOG(Info, format, ##__VA_ARGS__)
+#define DLOGV(format, ...) DLOG(Verbose, format, ##__VA_ARGS__)
+
+namespace sde {
+
+enum LogTag {
+ kTagNone = 0, //!< Log tag name is not specified.
+ kTagCore, //!< Log is tagged for display core.
+ kTagStrategy, //!< Log is tagged for composition strategy.
+};
+
+class Debug {
+ public:
+ // Log handlers
+ static void Error(const LogTag &tag, const char *format, ...);
+ static void Warning(const LogTag &tag, const char *format, ...);
+ static void Info(const LogTag &tag, const char *format, ...);
+ static void Verbose(const LogTag &tag, const char *format, ...);
+
+ // Debug properties
+ static bool IsVirtualDriver() { return debug_.virtual_driver_; }
+
+ private:
+ Debug();
+ bool virtual_driver_;
+ static Debug debug_;
+};
+
+} // namespace sde
+
+#endif // __DEBUG_H__
+
diff --git a/displayengine/include/utils/locker.h b/displayengine/include/utils/locker.h
new file mode 100644
index 0000000..2c1ef9a
--- /dev/null
+++ b/displayengine/include/utils/locker.h
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __LOCKER_H__
+#define __LOCKER_H__
+
+#include <stdint.h>
+#include <pthread.h>
+
+#define SCOPE_LOCK(locker) Locker::ScopeLock scopeLock(locker)
+
+namespace sde {
+
+class Locker {
+ public:
+ class ScopeLock {
+ public:
+ explicit ScopeLock(Locker& locker) : locker_(locker) {
+ locker_.Lock();
+ }
+
+ ~ScopeLock() {
+ locker_.Unlock();
+ }
+
+ private:
+ Locker &locker_;
+ };
+
+ Locker() {
+ pthread_mutex_init(&mutex_, 0);
+ pthread_cond_init(&condition_, 0);
+ }
+
+ ~Locker() {
+ pthread_mutex_destroy(&mutex_);
+ pthread_cond_destroy(&condition_);
+ }
+
+ void Lock() { pthread_mutex_lock(&mutex_); }
+ void Unlock() { pthread_mutex_unlock(&mutex_); }
+ void Signal() { pthread_cond_signal(&condition_); }
+ void Broadcast() { pthread_cond_broadcast(&condition_); }
+ void Wait() { pthread_cond_wait(&condition_, &mutex_); }
+ int WaitFinite(long int ms) {
+ struct timespec ts;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec + ms/1000;
+ ts.tv_nsec = tv.tv_usec*1000 + (ms%1000)*1000000;
+ ts.tv_sec += ts.tv_nsec/1000000000L;
+ ts.tv_nsec += ts.tv_nsec%1000000000L;
+ return pthread_cond_timedwait(&condition_, &mutex_, &ts);
+ }
+
+ private:
+ pthread_mutex_t mutex_;
+ pthread_cond_t condition_;
+};
+
+} // namespace sde
+
+#endif // __LOCKER_H__
+
diff --git a/displayengine/libs/common.mk b/displayengine/libs/common.mk
new file mode 100644
index 0000000..79ba738
--- /dev/null
+++ b/displayengine/libs/common.mk
@@ -0,0 +1,39 @@
+#Common headers
+common_includes := hardware/qcom/display/displayengine/include/
+common_includes += hardware/qcom/display/libgralloc/
+common_includes += hardware/qcom/display/libcopybit/
+
+common_header_export_path := qcom/display
+
+#Common libraries external to display HAL
+common_libs := liblog libutils libcutils libhardware
+
+#Common C flags
+common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
+common_flags += -Wconversion -Wall -Werror
+common_flags += -Wno-unused-parameter -Wno-unused-variable
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+ common_flags += -D__ARM_HAVE_NEON
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)), true)
+ common_flags += -DVENUS_COLOR_FORMAT
+endif
+
+ifeq ($(call is-board-platform-in-list, msm8994), true)
+ common_flags += -DMDSS_TARGET
+endif
+
+common_deps :=
+kernel_includes :=
+
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+# This check is to pick the kernel headers from the right location.
+# If the macro above is defined, we make the assumption that we have the kernel
+# available in the build tree.
+# If the macro is not present, the headers are picked from hardware/qcom/msmXXXX
+# failing which, they are picked from bionic.
+ common_deps += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+ kernel_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+endif
diff --git a/displayengine/libs/core/Android.mk b/displayengine/libs/core/Android.mk
new file mode 100644
index 0000000..496c899
--- /dev/null
+++ b/displayengine/libs/core/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH := $(call my-dir)
+include hardware/qcom/display/displayengine/libs/common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libsdecore
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"SDE\"
+LOCAL_SHARED_LIBRARIES := $(common_libs) libdl libsdeutils
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES := core_interface.cpp \
+ core_impl.cpp \
+ device_base.cpp \
+ device_primary.cpp \
+ device_hdmi.cpp \
+ device_virtual.cpp \
+ comp_manager.cpp \
+ strategy_default.cpp \
+ res_manager.cpp \
+ res_config.cpp \
+ offline_ctrl.cpp \
+ hw_interface.cpp \
+ hw_framebuffer.cpp \
+ dump_impl.cpp
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
new file mode 100644
index 0000000..560db52
--- /dev/null
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -0,0 +1,197 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "CompManager"
+#include <utils/debug.h>
+
+#include <dlfcn.h>
+#include <utils/constants.h>
+
+#include "comp_manager.h"
+
+namespace sde {
+
+CompManager::CompManager() : strategy_lib_(NULL), strategy_intf_(NULL) {
+}
+
+DisplayError CompManager::Init(const HWResourceInfo &hw_res_info) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ error = res_mgr_.Init(hw_res_info);
+ if (UNLIKELY(error != kErrorNone)) {
+ return error;
+ }
+
+ // Try to load strategy library & get handle to its interface.
+ // Default to GPU only composition on failure.
+ strategy_lib_ = ::dlopen(STRATEGY_LIBRARY_NAME, RTLD_NOW);
+ if (UNLIKELY(!strategy_lib_)) {
+ DLOGW("Unable to load = %s", STRATEGY_LIBRARY_NAME);
+ } else {
+ GetStrategyInterface get_strategy_intf = NULL;
+ void **sym = reinterpret_cast<void **>(&get_strategy_intf);
+ *sym = ::dlsym(strategy_lib_, GET_STRATEGY_INTERFACE_NAME);
+ if (UNLIKELY(!get_strategy_intf)) {
+ DLOGW("Unable to find symbol for %s", GET_STRATEGY_INTERFACE_NAME);
+ } else if (UNLIKELY(get_strategy_intf(&strategy_intf_) != kErrorNone)) {
+ DLOGW("Unable to get handle to strategy interface");
+ }
+ }
+
+ if (UNLIKELY(!strategy_intf_)) {
+ DLOGI("Using GPU only composition");
+ if (strategy_lib_) {
+ ::dlclose(strategy_lib_);
+ strategy_lib_ = NULL;
+ }
+ strategy_intf_ = &strategy_default_;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError CompManager::Deinit() {
+ SCOPE_LOCK(locker_);
+
+ if (strategy_lib_) {
+ ::dlclose(strategy_lib_);
+ }
+ res_mgr_.Deinit();
+
+ return kErrorNone;
+}
+
+DisplayError CompManager::RegisterDevice(DeviceType type, const HWDeviceAttributes &attributes,
+ Handle *device) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ CompManagerDevice *comp_mgr_device = new CompManagerDevice();
+ if (!comp_mgr_device) {
+ return kErrorMemory;
+ }
+
+ error = res_mgr_.RegisterDevice(type, attributes, &comp_mgr_device->res_mgr_device);
+ if (error != kErrorNone) {
+ delete comp_mgr_device;
+ return error;
+ }
+
+ comp_mgr_device->device_type = type;
+ *device = comp_mgr_device;
+
+ return kErrorNone;
+}
+
+DisplayError CompManager::UnregisterDevice(Handle device) {
+ SCOPE_LOCK(locker_);
+
+ CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
+
+ res_mgr_.UnregisterDevice(comp_mgr_device->res_mgr_device);
+ delete comp_mgr_device;
+
+ return kErrorNone;
+}
+
+DisplayError CompManager::Prepare(Handle device, HWLayers *hw_layers) {
+ SCOPE_LOCK(locker_);
+
+ CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
+ Handle &res_mgr_device = comp_mgr_device->res_mgr_device;
+
+ DisplayError error = kErrorNone;
+
+ comp_mgr_device->constraints.gpu_only = false;
+
+ // If validation for the best available composition strategy with driver has failed, just
+ // fallback to GPU composition.
+ if (UNLIKELY(hw_layers->info.flags)) {
+ // Did driver reject GPU composition as well? This will never happen.
+ if (UNLIKELY(hw_layers->info.flags & kFlagGPU)) {
+ DLOGE("Unexpected error. GPU composition validation failed.");
+ return kErrorHardware;
+ }
+
+ comp_mgr_device->constraints.gpu_only = true;
+ }
+
+ // Select a composition strategy, and try to allocate resources for it.
+ res_mgr_.Start(res_mgr_device);
+ while (true) {
+ error = strategy_intf_->GetNextStrategy(&comp_mgr_device->constraints, &hw_layers->info);
+ if (UNLIKELY(error != kErrorNone)) {
+ // Composition strategies exhausted. Resource Manager could not allocate resources even for
+ // GPU composition. This will never happen.
+ DLOGE("Unexpected failure. Composition strategies exhausted.");
+ return error;
+ }
+
+ error = res_mgr_.Acquire(res_mgr_device, hw_layers);
+ if (error != kErrorNone) {
+ // Not enough resources, try next strategy.
+ continue;
+ } else {
+ // Successfully selected and configured a composition strategy.
+ break;
+ }
+ }
+ res_mgr_.Stop(res_mgr_device);
+
+ return kErrorNone;
+}
+
+void CompManager::PostPrepare(Handle device, HWLayers *hw_layers) {
+ SCOPE_LOCK(locker_);
+}
+
+void CompManager::PostCommit(Handle device, HWLayers *hw_layers) {
+ SCOPE_LOCK(locker_);
+
+ CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
+
+ res_mgr_.PostCommit(comp_mgr_device->res_mgr_device, hw_layers);
+}
+
+void CompManager::Purge(Handle device) {
+ SCOPE_LOCK(locker_);
+
+ CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
+
+ res_mgr_.Purge(comp_mgr_device->res_mgr_device);
+}
+
+uint32_t CompManager::GetDump(uint8_t *buffer, uint32_t length) {
+ SCOPE_LOCK(locker_);
+
+ return 0;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/comp_manager.h b/displayengine/libs/core/comp_manager.h
new file mode 100644
index 0000000..e6954a8
--- /dev/null
+++ b/displayengine/libs/core/comp_manager.h
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __COMP_MANAGER_H__
+#define __COMP_MANAGER_H__
+
+#include <core/device_interface.h>
+
+#include "hw_interface.h"
+#include "strategy_default.h"
+#include "res_manager.h"
+#include "dump_impl.h"
+
+namespace sde {
+
+class CompManager : public DumpImpl {
+ public:
+ CompManager();
+ DisplayError Init(const HWResourceInfo &hw_res_info_);
+ DisplayError Deinit();
+ DisplayError RegisterDevice(DeviceType type, const HWDeviceAttributes &attributes,
+ Handle *device);
+ DisplayError UnregisterDevice(Handle device);
+ DisplayError Prepare(Handle device, HWLayers *hw_layers);
+ void PostPrepare(Handle device, HWLayers *hw_layers);
+ void PostCommit(Handle device, HWLayers *hw_layers);
+ void Purge(Handle device);
+
+ // DumpImpl method
+ virtual uint32_t GetDump(uint8_t *buffer, uint32_t length);
+
+ private:
+ struct CompManagerDevice {
+ StrategyConstraints constraints;
+ Handle res_mgr_device;
+ DeviceType device_type;
+ };
+
+ Locker locker_;
+ void *strategy_lib_;
+ StrategyInterface *strategy_intf_;
+ StrategyDefault strategy_default_;
+ ResManager res_mgr_;
+};
+
+} // namespace sde
+
+#endif // __COMP_MANAGER_H__
+
diff --git a/displayengine/libs/core/core_impl.cpp b/displayengine/libs/core/core_impl.cpp
new file mode 100644
index 0000000..9a1fa12
--- /dev/null
+++ b/displayengine/libs/core/core_impl.cpp
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "CoreImpl"
+#include <utils/debug.h>
+
+#include <utils/locker.h>
+#include <utils/constants.h>
+
+#include "core_impl.h"
+#include "device_primary.h"
+#include "device_hdmi.h"
+#include "device_virtual.h"
+
+namespace sde {
+
+CoreImpl::CoreImpl(CoreEventHandler *event_handler)
+ : event_handler_(event_handler), hw_intf_(NULL) {
+}
+
+DisplayError CoreImpl::Init() {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ error = HWInterface::Create(&hw_intf_);
+ if (UNLIKELY(error != kErrorNone)) {
+ return error;
+ }
+
+ HWResourceInfo hw_res_info;
+ error = hw_intf_->GetHWCapabilities(&hw_res_info);
+ if (UNLIKELY(error != kErrorNone)) {
+ HWInterface::Destroy(hw_intf_);
+ return error;
+ }
+
+ error = comp_mgr_.Init(hw_res_info);
+ if (UNLIKELY(error != kErrorNone)) {
+ HWInterface::Destroy(hw_intf_);
+ return error;
+ }
+
+ error = offline_ctrl_.Init(hw_intf_, hw_res_info);
+ if (UNLIKELY(error != kErrorNone)) {
+ comp_mgr_.Deinit();
+ HWInterface::Destroy(hw_intf_);
+ return error;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError CoreImpl::Deinit() {
+ SCOPE_LOCK(locker_);
+
+ offline_ctrl_.Deinit();
+ comp_mgr_.Deinit();
+ HWInterface::Destroy(hw_intf_);
+
+ return kErrorNone;
+}
+
+DisplayError CoreImpl::CreateDevice(DeviceType type, DeviceEventHandler *event_handler,
+ DeviceInterface **intf) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!event_handler || !intf)) {
+ return kErrorParameters;
+ }
+
+ DeviceBase *device_base = NULL;
+ switch (type) {
+ case kPrimary:
+ device_base = new DevicePrimary(event_handler, hw_intf_, &comp_mgr_);
+ break;
+
+ case kHWHDMI:
+ device_base = new DeviceHDMI(event_handler, hw_intf_, &comp_mgr_);
+ break;
+
+ case kVirtual:
+ device_base = new DeviceVirtual(event_handler, hw_intf_, &comp_mgr_);
+ break;
+
+ default:
+ DLOGE("Spurious device type %d", type);
+ return kErrorParameters;
+ }
+
+ if (UNLIKELY(!device_base)) {
+ return kErrorMemory;
+ }
+
+ DisplayError error = device_base->Init();
+ if (UNLIKELY(error != kErrorNone)) {
+ delete device_base;
+ return error;
+ }
+
+ *intf = device_base;
+ return kErrorNone;
+}
+
+DisplayError CoreImpl::DestroyDevice(DeviceInterface *intf) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!intf)) {
+ return kErrorParameters;
+ }
+
+ DeviceBase *device_base = static_cast<DeviceBase *>(intf);
+ device_base->Deinit();
+ delete device_base;
+
+ return kErrorNone;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/core_impl.h b/displayengine/libs/core/core_impl.h
new file mode 100644
index 0000000..16a01f2
--- /dev/null
+++ b/displayengine/libs/core/core_impl.h
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __CORE_IMPL_H__
+#define __CORE_IMPL_H__
+
+#include <core/core_interface.h>
+#include <private/strategy_interface.h>
+#include <utils/locker.h>
+
+#include "hw_interface.h"
+#include "comp_manager.h"
+#include "offline_ctrl.h"
+
+#define SET_REVISION(major, minor) ((major << 8) | minor)
+
+namespace sde {
+
+class CoreImpl : public CoreInterface {
+ public:
+ // This class implements display core interface revision 1.0.
+ static const uint16_t kRevision = SET_REVISION(1, 0);
+
+ explicit CoreImpl(CoreEventHandler *event_handler);
+ virtual ~CoreImpl() { }
+
+ // This method returns the interface revision for the current display core object.
+ // Future revisions will override this method and return the appropriate revision upon query.
+ virtual uint16_t GetRevision() { return kRevision; }
+ virtual DisplayError Init();
+ virtual DisplayError Deinit();
+
+ // Methods from core interface
+ virtual DisplayError CreateDevice(DeviceType type, DeviceEventHandler *event_handler,
+ DeviceInterface **intf);
+ virtual DisplayError DestroyDevice(DeviceInterface *intf);
+
+ protected:
+ Locker locker_;
+ CoreEventHandler *event_handler_;
+ HWInterface *hw_intf_;
+ CompManager comp_mgr_;
+ OfflineCtrl offline_ctrl_;
+};
+
+} // namespace sde
+
+#endif // __CORE_IMPL_H__
+
diff --git a/displayengine/libs/core/core_interface.cpp b/displayengine/libs/core/core_interface.cpp
new file mode 100644
index 0000000..7cd85b0
--- /dev/null
+++ b/displayengine/libs/core/core_interface.cpp
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "CoreInterface"
+#include <utils/debug.h>
+
+#include <utils/locker.h>
+#include <utils/constants.h>
+
+#include "core_impl.h"
+
+#define GET_REVISION(version) (version >> 16)
+#define GET_DATA_ALIGNMENT(version) ((version >> 8) & 0xFF)
+#define GET_INSTRUCTION_SET(version) (version & 0xFF)
+
+namespace sde {
+
+// Currently, we support only one client and one session for display core. So, create a global
+// singleton core object.
+struct CoreSingleton {
+ CoreSingleton() : core_impl(NULL) { }
+
+ CoreImpl *core_impl;
+ Locker locker;
+} g_core;
+
+DisplayError CoreInterface::CreateCore(CoreEventHandler *event_handler, CoreInterface **interface,
+ uint32_t client_version) {
+ SCOPE_LOCK(g_core.locker);
+
+ if (UNLIKELY(!event_handler || !interface)) {
+ return kErrorParameters;
+ }
+
+ // Check compatibility of client and core.
+ uint32_t lib_version = CORE_VERSION_TAG;
+ if (UNLIKELY(!interface)) {
+ return kErrorParameters;
+ } else if (UNLIKELY(GET_REVISION(client_version) > GET_REVISION(lib_version))) {
+ return kErrorVersion;
+ } else if (UNLIKELY(GET_DATA_ALIGNMENT(client_version) != GET_DATA_ALIGNMENT(lib_version))) {
+ return kErrorDataAlignment;
+ } else if (UNLIKELY(GET_INSTRUCTION_SET(client_version) != GET_INSTRUCTION_SET(lib_version))) {
+ return kErrorInstructionSet;
+ }
+
+ CoreImpl *&core_impl = g_core.core_impl;
+ if (UNLIKELY(core_impl)) {
+ DLOGE("Only one display core session is supported at present.");
+ return kErrorUndefined;
+ }
+
+ // Create appropriate CoreImpl object based on client version.
+ if (GET_REVISION(client_version) == CoreImpl::kRevision) {
+ core_impl = new CoreImpl(event_handler);
+ } else {
+ return kErrorNotSupported;
+ }
+
+ if (UNLIKELY(!core_impl)) {
+ return kErrorMemory;
+ }
+
+ DisplayError displayError = core_impl->Init();
+ if (UNLIKELY(displayError != kErrorNone)) {
+ delete core_impl;
+ core_impl = NULL;
+ return displayError;
+ }
+
+ *interface = core_impl;
+ DLOGI("Open interface handle = %p", *interface);
+
+ return kErrorNone;
+}
+
+DisplayError CoreInterface::DestroyCore() {
+ SCOPE_LOCK(g_core.locker);
+
+ DLOGI("Close handle");
+
+ CoreImpl *&core_impl = g_core.core_impl;
+ if (UNLIKELY(!core_impl)) {
+ return kErrorUndefined;
+ }
+
+ core_impl->Deinit();
+ delete core_impl;
+ core_impl = NULL;
+
+ return kErrorNone;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/device_base.cpp b/displayengine/libs/core/device_base.cpp
new file mode 100644
index 0000000..f991903
--- /dev/null
+++ b/displayengine/libs/core/device_base.cpp
@@ -0,0 +1,304 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "DeviceBase"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "device_base.h"
+
+namespace sde {
+
+DeviceBase::DeviceBase(DeviceType device_type, DeviceEventHandler *event_handler,
+ HWBlockType hw_block_type, HWInterface *hw_intf, CompManager *comp_manager)
+ : 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),
+ comp_mgr_device_(0), device_attributes_(NULL), num_modes_(0), active_mode_index_(0),
+ pending_commit_(false), vsync_enable_(false) {
+}
+
+DisplayError DeviceBase::Init() {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ error = hw_intf_->Open(hw_block_type_, &hw_device_, this);
+ if (UNLIKELY(error != kErrorNone)) {
+ return error;
+ }
+
+ error = hw_intf_->GetNumDeviceAttributes(hw_device_, &num_modes_);
+ if (UNLIKELY(error != kErrorNone)) {
+ goto CleanupOnError;
+ }
+
+ device_attributes_ = new HWDeviceAttributes[num_modes_];
+ if (!device_attributes_) {
+ error = kErrorMemory;
+ goto CleanupOnError;
+ }
+
+ for (uint32_t i = 0; i < num_modes_; i++) {
+ error = hw_intf_->GetDeviceAttributes(hw_device_, &device_attributes_[i], i);
+ if (UNLIKELY(error != kErrorNone)) {
+ goto CleanupOnError;
+ }
+ }
+
+ active_mode_index_ = 0;
+
+ error = comp_manager_->RegisterDevice(device_type_, device_attributes_[active_mode_index_],
+ &comp_mgr_device_);
+ if (UNLIKELY(error != kErrorNone)) {
+ goto CleanupOnError;
+ }
+
+ return kErrorNone;
+
+CleanupOnError:
+ comp_manager_->UnregisterDevice(comp_mgr_device_);
+
+ if (device_attributes_) {
+ delete[] device_attributes_;
+ }
+
+ hw_intf_->Close(hw_device_);
+
+ return error;
+}
+
+DisplayError DeviceBase::Deinit() {
+ SCOPE_LOCK(locker_);
+
+ comp_manager_->UnregisterDevice(comp_mgr_device_);
+ delete[] device_attributes_;
+ hw_intf_->Close(hw_device_);
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::Prepare(LayerStack *layer_stack) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ if (UNLIKELY(!layer_stack)) {
+ return kErrorParameters;
+ }
+
+ pending_commit_ = false;
+
+ if (LIKELY(state_ == kStateOn)) {
+ // Clean hw layers for reuse.
+ hw_layers_.info.Reset();
+ hw_layers_.info.stack = layer_stack;
+
+ while (true) {
+ error = comp_manager_->Prepare(comp_mgr_device_, &hw_layers_);
+ if (UNLIKELY(error != kErrorNone)) {
+ break;
+ }
+
+ error = hw_intf_->Validate(hw_device_, &hw_layers_);
+ if (LIKELY(error == kErrorNone)) {
+ // Strategy is successful now, wait for Commit().
+ comp_manager_->PostPrepare(comp_mgr_device_, &hw_layers_);
+ pending_commit_ = true;
+ break;
+ }
+ }
+ }
+
+ return error;
+}
+
+DisplayError DeviceBase::Commit(LayerStack *layer_stack) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ if (UNLIKELY(!layer_stack)) {
+ return kErrorParameters;
+ }
+
+ if (UNLIKELY(!pending_commit_)) {
+ DLOGE("Commit: Corresponding Prepare() is not called.");
+ return kErrorUndefined;
+ }
+
+ if (LIKELY(state_ == kStateOn)) {
+ error = hw_intf_->Commit(hw_device_, &hw_layers_);
+ if (LIKELY(error == kErrorNone)) {
+ comp_manager_->PostCommit(comp_mgr_device_, &hw_layers_);
+ } else {
+ DLOGE("Unexpected error. Commit failed on driver.");
+ }
+ }
+
+ pending_commit_ = false;
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::GetDeviceState(DeviceState *state) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!state)) {
+ return kErrorParameters;
+ }
+
+ *state = state_;
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::GetNumVariableInfoConfigs(uint32_t *count) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!count)) {
+ return kErrorParameters;
+ }
+
+ *count = num_modes_;
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::GetConfig(DeviceConfigFixedInfo *fixed_info) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!fixed_info)) {
+ return kErrorParameters;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::GetConfig(DeviceConfigVariableInfo *variable_info, uint32_t mode) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!variable_info || mode >= num_modes_)) {
+ return kErrorParameters;
+ }
+
+ *variable_info = device_attributes_[mode];
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::GetVSyncState(bool *enabled) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!enabled)) {
+ return kErrorParameters;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::SetDeviceState(DeviceState state) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ DLOGI("Set state: %d", state);
+
+ if (UNLIKELY(state == state_)) {
+ DLOGI("Same state transition is requested.");
+ return kErrorNone;
+ }
+
+ switch (state) {
+ case kStateOff:
+ comp_manager_->Purge(comp_mgr_device_);
+ error = hw_intf_->PowerOff(hw_device_);
+ break;
+
+ case kStateOn:
+ error = hw_intf_->PowerOn(hw_device_);
+ break;
+
+ case kStateDoze:
+ error = hw_intf_->Doze(hw_device_);
+ break;
+
+ case kStateStandby:
+ error = hw_intf_->Standby(hw_device_);
+ break;
+
+ default:
+ DLOGE("Spurious state %d transition requested.", state);
+ break;
+ }
+
+ if (UNLIKELY(error == kErrorNone)) {
+ state_ = state;
+ }
+
+ return error;
+}
+
+DisplayError DeviceBase::SetConfig(uint32_t mode) {
+ SCOPE_LOCK(locker_);
+
+ return kErrorNone;
+}
+
+DisplayError DeviceBase::SetVSyncState(bool enable) {
+ 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;
+}
+
+uint32_t DeviceBase::GetDump(uint8_t *buffer, uint32_t length) {
+ SCOPE_LOCK(locker_);
+
+ return 0;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/device_base.h b/displayengine/libs/core/device_base.h
new file mode 100644
index 0000000..458983c
--- /dev/null
+++ b/displayengine/libs/core/device_base.h
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEVICE_BASE_H__
+#define __DEVICE_BASE_H__
+
+#include <core/device_interface.h>
+#include <private/strategy_interface.h>
+#include <utils/locker.h>
+
+#include "hw_interface.h"
+#include "comp_manager.h"
+
+namespace sde {
+
+class DeviceBase : public DeviceInterface, DumpImpl, HWEventHandler {
+ public:
+ DeviceBase(DeviceType device_type, DeviceEventHandler *event_handler,
+ HWBlockType hw_block_type, HWInterface *hw_intf, CompManager *comp_manager);
+ virtual ~DeviceBase() { }
+ virtual DisplayError Init();
+ virtual DisplayError Deinit();
+ virtual DisplayError Prepare(LayerStack *layer_stack);
+ virtual DisplayError Commit(LayerStack *layer_stack);
+ virtual DisplayError GetDeviceState(DeviceState *state);
+ virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
+ virtual DisplayError GetConfig(DeviceConfigFixedInfo *fixed_info);
+ virtual DisplayError GetConfig(DeviceConfigVariableInfo *variable_info, uint32_t mode);
+ virtual DisplayError GetVSyncState(bool *enabled);
+ virtual DisplayError SetDeviceState(DeviceState state);
+ virtual DisplayError SetConfig(uint32_t mode);
+ virtual DisplayError SetVSyncState(bool enable);
+
+ // DumpImpl method
+ 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:
+ Locker locker_;
+ DeviceType device_type_;
+ DeviceEventHandler *event_handler_;
+ HWBlockType hw_block_type_;
+ HWInterface *hw_intf_;
+ CompManager *comp_manager_;
+ DeviceState state_;
+ Handle hw_device_;
+ Handle comp_mgr_device_;
+ HWDeviceAttributes *device_attributes_;
+ uint32_t num_modes_;
+ uint32_t active_mode_index_;
+ HWLayers hw_layers_;
+ bool pending_commit_;
+ bool vsync_enable_;
+};
+
+} // namespace sde
+
+#endif // __DEVICE_BASE_H__
+
diff --git a/displayengine/libs/core/device_hdmi.cpp b/displayengine/libs/core/device_hdmi.cpp
new file mode 100644
index 0000000..a7c8c4f
--- /dev/null
+++ b/displayengine/libs/core/device_hdmi.cpp
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "DeviceHDMI"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "device_hdmi.h"
+
+namespace sde {
+
+DeviceHDMI::DeviceHDMI(DeviceEventHandler *event_handler, HWInterface *hw_intf,
+ CompManager *comp_manager)
+ : DeviceBase(kHDMI, event_handler, kHWHDMI, hw_intf, comp_manager) {
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/device_hdmi.h b/displayengine/libs/core/device_hdmi.h
new file mode 100644
index 0000000..7d8cbc6
--- /dev/null
+++ b/displayengine/libs/core/device_hdmi.h
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEVICE_HDMI_H__
+#define __DEVICE_HDMI_H__
+
+#include "device_base.h"
+
+namespace sde {
+
+class DeviceHDMI : public DeviceBase {
+ public:
+ DeviceHDMI(DeviceEventHandler *event_handler, HWInterface *hw_intf, CompManager *comp_manager);
+};
+
+} // namespace sde
+
+#endif // __DEVICE_HDMI_H__
+
diff --git a/displayengine/libs/core/device_primary.cpp b/displayengine/libs/core/device_primary.cpp
new file mode 100644
index 0000000..c5d45b8
--- /dev/null
+++ b/displayengine/libs/core/device_primary.cpp
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "DevicePrimary"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "device_primary.h"
+
+namespace sde {
+
+DevicePrimary::DevicePrimary(DeviceEventHandler *event_handler, HWInterface *hw_intf,
+ CompManager *comp_manager)
+ : DeviceBase(kPrimary, event_handler, kHWPrimary, hw_intf, comp_manager) {
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/device_primary.h b/displayengine/libs/core/device_primary.h
new file mode 100644
index 0000000..771a6f7
--- /dev/null
+++ b/displayengine/libs/core/device_primary.h
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEVICE_PRIMARY_H__
+#define __DEVICE_PRIMARY_H__
+
+#include "device_base.h"
+
+namespace sde {
+
+class DevicePrimary : public DeviceBase {
+ public:
+ DevicePrimary(DeviceEventHandler *event_handler, HWInterface *hw_intf, CompManager *comp_manager);
+};
+
+} // namespace sde
+
+#endif // __DEVICE_PRIMARY_H__
+
diff --git a/displayengine/libs/core/device_virtual.cpp b/displayengine/libs/core/device_virtual.cpp
new file mode 100644
index 0000000..4e18f93
--- /dev/null
+++ b/displayengine/libs/core/device_virtual.cpp
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "DeviceVirtual"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "device_virtual.h"
+
+namespace sde {
+
+DeviceVirtual::DeviceVirtual(DeviceEventHandler *event_handler, HWInterface *hw_intf,
+ CompManager *comp_manager)
+ : DeviceBase(kVirtual, event_handler, kHWBlockMax, hw_intf, comp_manager) {
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/device_virtual.h b/displayengine/libs/core/device_virtual.h
new file mode 100644
index 0000000..e279f12
--- /dev/null
+++ b/displayengine/libs/core/device_virtual.h
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DEVICE_VIRTUAL_H__
+#define __DEVICE_VIRTUAL_H__
+
+#include "device_base.h"
+
+namespace sde {
+
+class DeviceVirtual : public DeviceBase {
+ public:
+ DeviceVirtual(DeviceEventHandler *event_handler, HWInterface *hw_intf, CompManager *comp_manager);
+};
+
+} // namespace sde
+
+#endif // __DEVICE_VIRTUAL_H__
+
diff --git a/displayengine/libs/core/dump_impl.cpp b/displayengine/libs/core/dump_impl.cpp
new file mode 100644
index 0000000..b15573c
--- /dev/null
+++ b/displayengine/libs/core/dump_impl.cpp
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "DumpInterface"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "dump_impl.h"
+
+namespace sde {
+
+DumpImpl* DumpImpl::dump_list_[] = { 0 };
+uint32_t DumpImpl::dump_count_ = 0;
+
+DisplayError DumpInterface::GetDump(uint8_t *buffer, uint32_t length, uint32_t *filled) {
+ if (!buffer || !length || !filled) {
+ return kErrorParameters;
+ }
+
+ DumpImpl::GetDump(buffer, length, filled);
+ return kErrorNone;
+}
+
+DumpImpl::DumpImpl() {
+ Register(this);
+}
+
+DumpImpl::~DumpImpl() {
+ Unregister(this);
+}
+
+// Caller has to ensure that it does not create or destroy devices while using dump interface.
+void DumpImpl::GetDump(uint8_t *buffer, uint32_t length, uint32_t *filled) {
+ *filled = 0;
+ for (uint32_t i = 0; (i < DumpImpl::dump_count_) && (*filled < length); i++) {
+ *filled += DumpImpl::dump_list_[i]->GetDump(buffer + *filled, length - *filled);
+ }
+}
+
+// Every object is created or destroyed through display core only, which itself protects the
+// the access, so no need to protect registration or de-registration.
+void DumpImpl::Register(DumpImpl *dump_impl) {
+ if (dump_count_ < kMaxDumpObjects) {
+ dump_list_[dump_count_] = dump_impl;
+ dump_count_++;
+ }
+}
+
+void DumpImpl::Unregister(DumpImpl *dump_impl) {
+ for (uint32_t i = 0; i < dump_count_; i++) {
+ if (dump_list_[i] == dump_impl) {
+ dump_count_--;
+ for (; i < dump_count_; i++) {
+ dump_list_[i] = dump_list_[i + 1];
+ }
+ }
+ }
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/dump_impl.h b/displayengine/libs/core/dump_impl.h
new file mode 100644
index 0000000..7d652ec
--- /dev/null
+++ b/displayengine/libs/core/dump_impl.h
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __DUMP_IMPL_H__
+#define __DUMP_IMPL_H__
+
+#include <core/dump_interface.h>
+
+namespace sde {
+
+class DumpImpl {
+ public:
+ // To be implemented in the modules which will add dump information to final dump buffer.
+ // buffer address & length will be already adjusted before calling into these modules.
+ virtual uint32_t GetDump(uint8_t *buffer, uint32_t length) = 0;
+ static void GetDump(uint8_t *buffer, uint32_t length, uint32_t *filled);
+
+ protected:
+ DumpImpl();
+ virtual ~DumpImpl();
+
+ private:
+ static const uint32_t kMaxDumpObjects = 32;
+
+ static void Register(DumpImpl *dump_impl);
+ static void Unregister(DumpImpl *dump_impl);
+
+ static DumpImpl *dump_list_[kMaxDumpObjects];
+ static uint32_t dump_count_;
+
+ friend DumpInterface;
+};
+
+} // namespace sde
+
+#endif // __DUMP_IMPL_H__
+
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
new file mode 100644
index 0000000..3057fa2
--- /dev/null
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -0,0 +1,531 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "HWFrameBuffer"
+#include <utils/debug.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#include <sys/resource.h>
+#include <sys/prctl.h>
+#include <pthread.h>
+#include <utils/constants.h>
+
+#include "hw_framebuffer.h"
+
+#define IOCTL_LOGE(ioctl) DLOGE("ioctl %s, errno = %d, desc = %s", #ioctl, errno, strerror(errno))
+
+#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
+extern int virtual_ioctl(int fd, int cmd, ...);
+extern int virtual_open(const char *file_name, int access, ...);
+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
+
+namespace sde {
+
+HWFrameBuffer::HWFrameBuffer() : event_thread_name_("SDE_EventThread"), fake_vsync_(false),
+ exit_threads_(false) {
+ // Pointer to actual driver interfaces.
+ ioctl_ = ::ioctl;
+ open_ = ::open;
+ close_ = ::close;
+ poll_ = ::poll;
+ pread_ = ::pread;
+
+#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
+ // If debug property to use virtual driver is set, point to virtual driver interfaces.
+ if (Debug::IsVirtualDriver()) {
+ ioctl_ = virtual_ioctl;
+ open_ = virtual_open;
+ close_ = virtual_close;
+ poll_ = virtual_poll;
+ pread_ = virtual_pread;
+ }
+#endif
+}
+
+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;
+
+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() {
+ 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;
+}
+
+DisplayError HWFrameBuffer::GetHWCapabilities(HWResourceInfo *hw_res_info) {
+ // Hardcode for 8084 for now.
+ hw_res_info->mdp_version = 500;
+ hw_res_info->hw_revision = 0x10030001;
+ hw_res_info->num_dma_pipe = 2;
+ hw_res_info->num_vig_pipe = 4;
+ hw_res_info->num_rgb_pipe = 4;
+ hw_res_info->num_rotator = 2;
+ hw_res_info->num_control = 5;
+ hw_res_info->num_mixer_to_disp = 4;
+ hw_res_info->max_scale_up = 20;
+ hw_res_info->max_scale_down = 4;
+ hw_res_info->has_non_scalar_rgb = true;
+ hw_res_info->is_src_split = true;
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::Open(HWBlockType type, Handle *device, HWEventHandler* eventhandler) {
+ DisplayError error = kErrorNone;
+
+ HWContext *hw_context = new HWContext();
+ if (UNLIKELY(!hw_context)) {
+ return kErrorMemory;
+ }
+
+ int device_id = 0;
+ switch (type) {
+ case kHWPrimary:
+ device_id = 0;
+ break;
+ default:
+ break;
+ }
+
+ char device_name[64] = {0};
+ snprintf(device_name, sizeof(device_name), "%s%d", "/dev/graphics/fb", device_id);
+
+ hw_context->device_fd = open_(device_name, O_RDWR);
+ if (UNLIKELY(hw_context->device_fd < 0)) {
+ DLOGE("open %s failed.", device_name);
+ error = kErrorResources;
+ delete hw_context;
+ }
+
+ *device = hw_context;
+ event_handler_[device_id] = eventhandler;
+
+ return error;
+}
+
+DisplayError HWFrameBuffer::Close(Handle device) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ close_(hw_context->device_fd);
+ delete hw_context;
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::GetNumDeviceAttributes(Handle device, uint32_t *count) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ // TODO(user): Query modes
+ *count = 1;
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::GetDeviceAttributes(Handle device,
+ HWDeviceAttributes *device_attributes,
+ uint32_t mode) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+ int &device_fd = hw_context->device_fd;
+
+ // TODO(user): Query for respective mode index.
+
+ // Variable screen info
+ STRUCT_VAR(fb_var_screeninfo, var_screeninfo);
+ if (UNLIKELY(ioctl_(device_fd, FBIOGET_VSCREENINFO, &var_screeninfo) == -1)) {
+ IOCTL_LOGE(FBIOGET_VSCREENINFO);
+ return kErrorHardware;
+ }
+
+ // Frame rate
+ STRUCT_VAR(msmfb_metadata, meta_data);
+ meta_data.op = metadata_op_frame_rate;
+ if (UNLIKELY(ioctl_(device_fd, MSMFB_METADATA_GET, &meta_data) == -1)) {
+ IOCTL_LOGE(MSMFB_METADATA_GET);
+ return kErrorHardware;
+ }
+
+ // If driver doesn't return width/height information, default to 160 dpi
+ if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) {
+ var_screeninfo.width = INT((FLOAT(var_screeninfo.xres) * 25.4f)/160.0f + 0.5f);
+ var_screeninfo.height = INT((FLOAT(var_screeninfo.yres) * 25.4f)/160.0f + 0.5f);
+ }
+
+ device_attributes->x_pixels = var_screeninfo.xres;
+ device_attributes->y_pixels = var_screeninfo.yres;
+ device_attributes->x_dpi = (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width);
+ device_attributes->y_dpi = (FLOAT(var_screeninfo.yres) * 25.4f) / FLOAT(var_screeninfo.height);
+ device_attributes->vsync_period_ns = UINT32(1000000000L / FLOAT(meta_data.data.panel_frame_rate));
+
+ // TODO(user): set panel information from sysfs
+ device_attributes->is_device_split = true;
+ device_attributes->split_left = device_attributes->x_pixels / 2;
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::PowerOn(Handle device) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ if (UNLIKELY(ioctl_(hw_context->device_fd, FBIOBLANK, FB_BLANK_UNBLANK) == -1)) {
+ IOCTL_LOGE(FB_BLANK_UNBLANK);
+ return kErrorHardware;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::PowerOff(Handle device) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ if (UNLIKELY(ioctl_(hw_context->device_fd, FBIOBLANK, FB_BLANK_POWERDOWN) == -1)) {
+ IOCTL_LOGE(FB_BLANK_POWERDOWN);
+ return kErrorHardware;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::Doze(Handle device) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::Standby(Handle device) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ 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) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ return kErrorNone;
+}
+
+DisplayError HWFrameBuffer::Commit(Handle device, HWLayers *hw_layers) {
+ HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+ HWLayersInfo &hw_layer_info = hw_layers->info;
+
+ // Assuming left & right both pipe are required, maximum possible number of overlays.
+ uint32_t max_overlay_count = hw_layer_info.count * 2;
+
+ int acquire_fences[hw_layer_info.count]; // NOLINT
+ int release_fence = -1;
+ int retire_fence = -1;
+ uint32_t acquire_fence_count = 0;
+ STRUCT_VAR_ARRAY(mdp_overlay, overlay_array, max_overlay_count);
+ STRUCT_VAR_ARRAY(msmfb_overlay_data, data_array, max_overlay_count);
+
+ LayerStack *stack = hw_layer_info.stack;
+ uint32_t num_overlays = 0;
+ for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+ uint32_t layer_index = hw_layer_info.index[i];
+ Layer &layer = stack->layers[layer_index];
+ LayerBuffer *input_buffer = layer.input_buffer;
+ HWLayerConfig &config = hw_layers->config[i];
+ HWPipeInfo &left_pipe = config.left_pipe;
+
+ // Configure left pipe
+ mdp_overlay &left_overlay = overlay_array[num_overlays];
+ msmfb_overlay_data &left_data = data_array[num_overlays];
+
+ left_overlay.id = left_pipe.pipe_id;
+ left_overlay.flags |= MDP_BLEND_FG_PREMULT;
+ left_overlay.transp_mask = 0xffffffff;
+ left_overlay.z_order = i;
+ left_overlay.alpha = layer.plane_alpha;
+ left_overlay.src.width = input_buffer->planes[0].stride;
+ left_overlay.src.height = input_buffer->height;
+ SetBlending(&left_overlay.blend_op, layer.blending);
+ SetFormat(&left_overlay.src.format, layer.input_buffer->format);
+ SetRect(&left_overlay.src_rect, left_pipe.src_roi);
+ SetRect(&left_overlay.dst_rect, left_pipe.dst_roi);
+ left_data.id = left_pipe.pipe_id;
+ left_data.data.memory_id = input_buffer->planes[0].fd;
+ left_data.data.offset = input_buffer->planes[0].offset;
+
+ num_overlays++;
+
+ // Configure right pipe
+ if (config.is_right_pipe) {
+ HWPipeInfo &right_pipe = config.right_pipe;
+ mdp_overlay &right_overlay = overlay_array[num_overlays];
+ msmfb_overlay_data &right_data = data_array[num_overlays];
+
+ right_overlay = left_overlay;
+ right_data = left_data;
+ right_overlay.id = right_pipe.pipe_id;
+ right_data.id = right_pipe.pipe_id;
+ SetRect(&right_overlay.src_rect, right_pipe.src_roi);
+ SetRect(&right_overlay.dst_rect, right_pipe.dst_roi);
+
+ num_overlays++;
+ }
+
+ if (input_buffer->acquire_fence_fd >= 0) {
+ acquire_fences[acquire_fence_count] = input_buffer->acquire_fence_fd;
+ acquire_fence_count++;
+ }
+ }
+
+ mdp_overlay *overlay_list[num_overlays];
+ msmfb_overlay_data *data_list[num_overlays];
+ for (uint32_t i = 0; i < num_overlays; i++) {
+ overlay_list[i] = &overlay_array[i];
+ data_list[i] = &data_array[i];
+ }
+
+ // TODO(user): Replace with Atomic commit call.
+ STRUCT_VAR(mdp_atomic_commit, atomic_commit);
+ atomic_commit.overlay_list = overlay_list;
+ atomic_commit.data_list = data_list;
+ atomic_commit.num_overlays = num_overlays;
+ atomic_commit.buf_sync.acq_fen_fd = acquire_fences;
+ atomic_commit.buf_sync.acq_fen_fd_cnt = acquire_fence_count;
+ atomic_commit.buf_sync.rel_fen_fd = &release_fence;
+ atomic_commit.buf_sync.retire_fen_fd = &retire_fence;
+ atomic_commit.buf_sync.flags = MDP_BUF_SYNC_FLAG_RETIRE_FENCE;
+
+ if (UNLIKELY(ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &atomic_commit) == -1)) {
+ IOCTL_LOGE(MSMFB_ATOMIC_COMMIT);
+ return kErrorHardware;
+ }
+
+ // MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
+ // layers being composed by MDP.
+ stack->retire_fence_fd = retire_fence;
+ for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+ uint32_t layer_index = hw_layer_info.index[i];
+ Layer &layer = stack->layers[layer_index];
+ LayerBuffer *input_buffer = layer.input_buffer;
+ input_buffer->release_fence_fd = dup(release_fence);
+ }
+ close(release_fence);
+
+ return kErrorNone;
+}
+
+void HWFrameBuffer::SetFormat(uint32_t *target, const LayerBufferFormat &source) {
+ switch (source) {
+ default:
+ *target = MDP_RGBA_8888;
+ break;
+ }
+}
+
+void HWFrameBuffer::SetBlending(uint32_t *target, const LayerBlending &source) {
+ switch (source) {
+ case kBlendingPremultiplied:
+ *target = BLEND_OP_PREMULTIPLIED;
+ break;
+
+ case kBlendingCoverage:
+ *target = BLEND_OP_COVERAGE;
+ break;
+
+ default:
+ *target = BLEND_OP_NOT_DEFINED;
+ break;
+ }
+}
+
+void HWFrameBuffer::SetRect(mdp_rect *target, const LayerRect &source) {
+ target->x = INT(ceilf(source.left));
+ target->y = INT(ceilf(source.top));
+ target->w = INT(floorf(source.right)) - target->x;
+ target->h = INT(floorf(source.bottom)) - target->y;
+}
+
+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
diff --git a/displayengine/libs/core/hw_framebuffer.h b/displayengine/libs/core/hw_framebuffer.h
new file mode 100644
index 0000000..b64e869
--- /dev/null
+++ b/displayengine/libs/core/hw_framebuffer.h
@@ -0,0 +1,99 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_FRAMEBUFFER_H__
+#define __HW_FRAMEBUFFER_H__
+
+#include <linux/msm_mdp.h>
+#include <poll.h>
+#include <pthread.h>
+#include "hw_interface.h"
+
+namespace sde {
+
+class HWFrameBuffer : public HWInterface {
+ public:
+ HWFrameBuffer();
+ DisplayError Init();
+ DisplayError Deinit();
+ virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info);
+ virtual DisplayError Open(HWBlockType type, Handle *device, HWEventHandler *eventhandler);
+ virtual DisplayError Close(Handle device);
+ virtual DisplayError GetNumDeviceAttributes(Handle device, uint32_t *count);
+ virtual DisplayError GetDeviceAttributes(Handle device, HWDeviceAttributes *device_attributes,
+ uint32_t mode);
+ virtual DisplayError PowerOn(Handle device);
+ virtual DisplayError PowerOff(Handle device);
+ virtual DisplayError Doze(Handle device);
+ virtual DisplayError SetVSyncState(Handle device, bool enable);
+ virtual DisplayError Standby(Handle device);
+ virtual DisplayError Validate(Handle device, HWLayers *hw_layers);
+ virtual DisplayError Commit(Handle device, HWLayers *hw_layers);
+
+ private:
+ struct HWContext {
+ HWBlockType type;
+ 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 SetBlending(uint32_t *target, const LayerBlending &source);
+ inline void SetRect(mdp_rect *target, const LayerRect &source);
+
+ // 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 (*open_)(const char *, 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
+
+#endif // __HW_FRAMEBUFFER_H__
+
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/hw_interface.cpp
new file mode 100644
index 0000000..f39cc21
--- /dev/null
+++ b/displayengine/libs/core/hw_interface.cpp
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "HWInterface"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "hw_interface.h"
+#include "hw_framebuffer.h"
+
+namespace sde {
+
+DisplayError HWInterface::Create(HWInterface **intf) {
+ DisplayError error = kErrorNone;
+ HWFrameBuffer *hw_frame_buffer = NULL;
+
+ hw_frame_buffer = new HWFrameBuffer();
+ error = hw_frame_buffer->Init();
+ if (UNLIKELY(error != kErrorNone)) {
+ delete hw_frame_buffer;
+ } else {
+ *intf = hw_frame_buffer;
+ }
+
+ return error;
+}
+
+DisplayError HWInterface::Destroy(HWInterface *intf) {
+ HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
+ hw_frame_buffer->Deinit();
+ delete hw_frame_buffer;
+ return kErrorNone;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
new file mode 100644
index 0000000..ddf631e
--- /dev/null
+++ b/displayengine/libs/core/hw_interface.h
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_INTERFACE_H__
+#define __HW_INTERFACE_H__
+
+#include <core/device_interface.h>
+#include <private/strategy_interface.h>
+#include <utils/constants.h>
+
+namespace sde {
+
+enum HWBlockType {
+ kHWPrimary,
+ kHWHDMI,
+ kHWWriteback0,
+ kHWWriteback1,
+ kHWWriteback2,
+ kHWBlockMax
+};
+
+struct HWResourceInfo {
+ uint32_t mdp_version;
+ uint32_t hw_revision;
+ uint32_t num_dma_pipe;
+ uint32_t num_vig_pipe;
+ uint32_t num_rgb_pipe;
+ uint32_t num_rotator;
+ uint32_t num_control;
+ uint32_t num_mixer_to_disp;
+ uint32_t smp_total;
+ uint32_t smp_size;
+ uint32_t num_smp_per_pipe;
+ uint32_t max_scale_up;
+ uint32_t max_scale_down;
+ uint32_t max_bandwidth_low;
+ uint32_t max_bandwidth_high;
+ bool has_bwc;
+ bool has_decimation;
+ bool has_non_scalar_rgb;
+ bool is_src_split;
+ bool has_microtile;
+
+ HWResourceInfo()
+ : mdp_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0),
+ num_rgb_pipe(0), num_rotator(0), num_control(0), num_mixer_to_disp(0), smp_total(0),
+ smp_size(0), num_smp_per_pipe(0), max_scale_up(0), max_scale_down(0), max_bandwidth_low(0),
+ max_bandwidth_high(0), has_bwc(false), has_decimation(false), has_non_scalar_rgb(false),
+ is_src_split(false), has_microtile(false) { }
+};
+
+struct HWPipeInfo {
+ uint32_t pipe_id;
+ LayerRect src_roi;
+ LayerRect dst_roi;
+
+ HWPipeInfo() : pipe_id(0) { }
+};
+
+struct HWLayerConfig {
+ bool use_non_dma_pipe;
+ bool is_right_pipe;
+ HWPipeInfo left_pipe;
+ HWPipeInfo right_pipe;
+
+ HWLayerConfig() : use_non_dma_pipe(false), is_right_pipe(true) { }
+};
+
+struct HWLayers {
+ HWLayersInfo info;
+ HWLayerConfig config[kNumLayersMax];
+};
+
+struct HWDeviceAttributes : DeviceConfigVariableInfo {
+ bool is_device_split;
+ uint32_t split_left;
+
+ 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 {
+ public:
+ static DisplayError Create(HWInterface **intf);
+ static DisplayError Destroy(HWInterface *intf);
+ virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info) = 0;
+ virtual DisplayError Open(HWBlockType type, Handle *device, HWEventHandler *eventhandler) = 0;
+ virtual DisplayError Close(Handle device) = 0;
+ virtual DisplayError GetNumDeviceAttributes(Handle device, uint32_t *count) = 0;
+ virtual DisplayError GetDeviceAttributes(Handle device, HWDeviceAttributes *device_attributes,
+ uint32_t mode) = 0;
+ virtual DisplayError PowerOn(Handle device) = 0;
+ virtual DisplayError PowerOff(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 Validate(Handle device, HWLayers *hw_layers) = 0;
+ virtual DisplayError Commit(Handle device, HWLayers *hw_layers) = 0;
+
+ protected:
+ virtual ~HWInterface() { }
+};
+
+} // namespace sde
+
+#endif // __HW_INTERFACE_H__
+
diff --git a/displayengine/libs/core/offline_ctrl.cpp b/displayengine/libs/core/offline_ctrl.cpp
new file mode 100644
index 0000000..be01cef
--- /dev/null
+++ b/displayengine/libs/core/offline_ctrl.cpp
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "OfflineCtrl"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "offline_ctrl.h"
+
+namespace sde {
+
+OfflineCtrl::OfflineCtrl() : hw_intf_(NULL) {
+}
+
+DisplayError OfflineCtrl::Init(HWInterface *hw_intf, HWResourceInfo hw_res_info) {
+ hw_intf_ = hw_intf;
+ return kErrorNone;
+}
+
+DisplayError OfflineCtrl::Deinit() {
+ return kErrorNone;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/offline_ctrl.h b/displayengine/libs/core/offline_ctrl.h
new file mode 100644
index 0000000..8987bb3
--- /dev/null
+++ b/displayengine/libs/core/offline_ctrl.h
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __OFFLINE_CTRL_H__
+#define __OFFLINE_CTRL_H__
+
+#include <utils/locker.h>
+
+#include "hw_interface.h"
+
+namespace sde {
+
+class OfflineCtrl {
+ public:
+ OfflineCtrl();
+ DisplayError Init(HWInterface *hw_intf, HWResourceInfo hw_res_info);
+ DisplayError Deinit();
+
+ private:
+ HWInterface *hw_intf_;
+};
+
+} // namespace sde
+
+#endif // __OFFLINE_CTRL_H__
+
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
new file mode 100644
index 0000000..0f71945
--- /dev/null
+++ b/displayengine/libs/core/res_config.cpp
@@ -0,0 +1,236 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "ResConfig"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+#include <math.h>
+
+#include "res_manager.h"
+
+namespace sde {
+
+DisplayError ResManager::Config(ResManagerDevice *res_mgr_device, HWLayers *hw_layers) {
+ HWBlockType hw_block_id = res_mgr_device->hw_block_id;
+ HWDeviceAttributes &device_attributes = res_mgr_device->device_attributes;
+ HWLayersInfo &layer_info = hw_layers->info;
+
+ for (uint32_t i = 0; i < layer_info.count; i++) {
+ Layer& layer = layer_info.stack->layers[layer_info.index[i]];
+ float w_scale, h_scale;
+ if (!IsValidDimension(layer, &w_scale, &h_scale)) {
+ DLOGV("Invalid dimension");
+ return kErrorNotSupported;
+ }
+
+ LayerRect scissor;
+ scissor.right = FLOAT(device_attributes.split_left);
+ scissor.bottom = FLOAT(device_attributes.y_pixels);
+ LayerRect crop = layer.src_rect;
+ LayerRect dst = layer.dst_rect;
+ LayerRect cropRight = crop;
+ LayerRect dstRight = dst;
+ CalculateCropRects(&crop, &dst, scissor, layer.transform);
+ HWPipeInfo *pipe_info = &hw_layers->config[i].left_pipe;
+
+ pipe_info->src_roi = crop;
+ pipe_info->dst_roi = dst;
+
+ float crop_width = cropRight.right - cropRight.left;
+ pipe_info = &hw_layers->config[i].right_pipe;
+ if ((dstRight.right - dstRight.left) > kMaxInterfaceWidth ||
+ crop_width > kMaxInterfaceWidth ||
+ ((hw_block_id == kHWPrimary) && hw_res_info_.is_src_split &&
+ (crop_width > device_attributes.split_left))) {
+ scissor.left = FLOAT(device_attributes.split_left);
+ scissor.top = 0.0f;
+ scissor.right = FLOAT(device_attributes.x_pixels);
+ scissor.bottom = FLOAT(device_attributes.y_pixels);
+ CalculateCropRects(&cropRight, &dstRight, scissor, layer.transform);
+ pipe_info->src_roi = cropRight;
+ pipe_info->dst_roi = dstRight;
+ pipe_info->pipe_id = -1;
+ } else {
+ // need not right pipe
+ pipe_info->pipe_id = 0;
+ }
+ }
+
+ return kErrorNone;
+}
+
+bool ResManager::IsValidDimension(const Layer& layer, float *width_scale, float *height_scale) {
+ if (IsNonIntegralSrcCrop(layer.src_rect)) {
+ return false;
+ }
+
+ LayerRect crop;
+ LayerRect dst;
+ IntegerizeRect(&crop, layer.src_rect);
+ IntegerizeRect(&dst, layer.dst_rect);
+
+ bool rotated90 = (static_cast<int>(layer.transform.rotation) == 90);
+ float crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
+ float crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
+ float dst_w = dst.right - dst.left;
+ float dst_h = dst.bottom - dst.top;
+
+ if ((dst_w < 1) || (dst_h < 1)) {
+ return false;
+ }
+
+ float w_scale = crop_w / dst_w;
+ float h_scale = crop_h / dst_h;
+
+ if ((crop_w < kMaxCropWidth) ||(crop_h < kMaxCropHeight)) {
+ return false;
+ }
+
+ if ((w_scale > 1.0f) || (h_scale > 1.0f)) {
+ const uint32_t max_scale_down = hw_res_info_.max_scale_down;
+
+ if (!hw_res_info_.has_decimation) {
+ if (crop_w > kMaxSourcePipeWidth || w_scale > max_scale_down || h_scale > max_scale_down) {
+ return false;
+ }
+ } else {
+ if (w_scale > max_scale_down || h_scale > max_scale_down) {
+ return false;
+ }
+ }
+ }
+
+ if (((w_scale < 1.0f) || (h_scale < 1.0f)) && (w_scale > 0.0f) && (h_scale > 0.0f)) {
+ const uint32_t max_scale_up = hw_res_info_.max_scale_up;
+ const float w_uscale = 1.0f / w_scale;
+ const float h_uscale = 1.0f / h_scale;
+
+ if (w_uscale > max_scale_up || h_uscale > max_scale_up) {
+ return false;
+ }
+ }
+
+ *width_scale = w_scale;
+ *height_scale = h_scale;
+
+ return true;
+}
+
+void ResManager::CalculateCut(float *left_cut_ratio,
+ float *top_cut_ratio, float *right_cut_ratio, float *bottom_cut_ratio,
+ const LayerTransform& transform) {
+ if (transform.flip_horizontal) {
+ Swap(*left_cut_ratio, *right_cut_ratio);
+ }
+
+ if (transform.flip_vertical) {
+ Swap(*top_cut_ratio, *bottom_cut_ratio);
+ }
+
+ if (UINT32(transform.rotation) == 90) {
+ // Anti clock swapping
+ float tmp_cut_ratio = *left_cut_ratio;
+ *left_cut_ratio = *top_cut_ratio;
+ *top_cut_ratio = *right_cut_ratio;
+ *right_cut_ratio = *bottom_cut_ratio;
+ *bottom_cut_ratio = tmp_cut_ratio;
+ }
+}
+
+void ResManager::CalculateCropRects(LayerRect *crop, LayerRect *dst,
+ const LayerRect& scissor, const LayerTransform& transform) {
+ float& crop_l = crop->left;
+ float& crop_t = crop->top;
+ float& crop_r = crop->right;
+ float& crop_b = crop->bottom;
+ float crop_w = crop->right - crop->left;
+ float crop_h = crop->bottom - crop->top;
+
+ float& dst_l = dst->left;
+ float& dst_t = dst->top;
+ float& dst_r = dst->right;
+ float& dst_b = dst->bottom;
+ float dst_w = (dst->right > dst->left) ? dst->right - dst->left :
+ dst->left - dst->right;
+ float dst_h = (dst->bottom > dst->top) ? dst->bottom > dst->top :
+ dst->top > dst->bottom;
+
+ const float& sci_l = scissor.left;
+ const float& sci_t = scissor.top;
+ const float& sci_r = scissor.right;
+ const float& sci_b = scissor.bottom;
+
+ float left_cut_ratio = 0.0, right_cut_ratio = 0.0, top_cut_ratio = 0.0,
+ bottom_cut_ratio = 0.0;
+
+ if (dst_l < sci_l) {
+ left_cut_ratio = (sci_l - dst_l) / dst_w;
+ dst_l = sci_l;
+ }
+
+ if (dst_r > sci_r) {
+ right_cut_ratio = (dst_r - sci_r) / dst_w;
+ dst_r = sci_r;
+ }
+
+ if (dst_t < sci_t) {
+ top_cut_ratio = (sci_t - dst_t) / (dst_h);
+ dst_t = sci_t;
+ }
+
+ if (dst_b > sci_b) {
+ bottom_cut_ratio = (dst_b - sci_b) / (dst_h);
+ dst_b = sci_b;
+ }
+
+ CalculateCut(&left_cut_ratio, &top_cut_ratio, &right_cut_ratio, &bottom_cut_ratio, transform);
+ crop_l += crop_w * left_cut_ratio;
+ crop_t += crop_h * top_cut_ratio;
+ crop_r -= crop_w * right_cut_ratio;
+ crop_b -= crop_h * bottom_cut_ratio;
+}
+
+bool ResManager::IsNonIntegralSrcCrop(const LayerRect& crop) {
+ if (crop.left - roundf(crop.left) ||
+ crop.top - roundf(crop.top) ||
+ crop.right - roundf(crop.right) ||
+ crop.bottom - roundf(crop.bottom)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void ResManager::IntegerizeRect(LayerRect *dst_rect, const LayerRect &src_rect) {
+ dst_rect->left = ceilf(src_rect.left);
+ dst_rect->top = ceilf(src_rect.top);
+ dst_rect->right = floorf(src_rect.right);
+ dst_rect->bottom = floorf(src_rect.bottom);
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
new file mode 100644
index 0000000..16060d8
--- /dev/null
+++ b/displayengine/libs/core/res_manager.cpp
@@ -0,0 +1,451 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "ResManager"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "res_manager.h"
+
+namespace sde {
+
+ResManager::ResManager()
+ : num_pipe_(0), vig_pipes_(NULL), rgb_pipes_(NULL), dma_pipes_(NULL), frame_start_(false) {
+}
+
+DisplayError ResManager::Init(const HWResourceInfo &hw_res_info) {
+ DLOGV("Init");
+
+ hw_res_info_ = hw_res_info;
+
+ DisplayError error = kErrorNone;
+
+ num_pipe_ = hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe + hw_res_info_.num_dma_pipe;
+
+ if (UNLIKELY(num_pipe_ > kPipeIdMax)) {
+ DLOGE("Number of pipe is over the limit! %d", num_pipe_);
+ return kErrorParameters;
+ }
+
+ // Init pipe info
+ vig_pipes_ = &src_pipes_[0];
+ rgb_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe];
+ dma_pipes_ = &src_pipes_[hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe];
+
+ for (uint32_t i = 0; i < hw_res_info_.num_vig_pipe; i++) {
+ vig_pipes_[i].type = kPipeTypeVIG;
+ vig_pipes_[i].index = i;
+ vig_pipes_[i].mdss_pipe_id = GetMdssPipeId(vig_pipes_[i].type, i);
+ }
+
+ for (uint32_t i = 0; i < hw_res_info_.num_rgb_pipe; i++) {
+ rgb_pipes_[i].type = kPipeTypeRGB;
+ rgb_pipes_[i].index = i + hw_res_info_.num_vig_pipe;
+ rgb_pipes_[i].mdss_pipe_id = GetMdssPipeId(rgb_pipes_[i].type, i);
+ }
+
+ for (uint32_t i = 0; i < hw_res_info_.num_dma_pipe; i++) {
+ dma_pipes_[i].type = kPipeTypeDMA;
+ dma_pipes_[i].index = i + hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe;
+ dma_pipes_[i].mdss_pipe_id = GetMdssPipeId(dma_pipes_[i].type, i);
+ }
+
+ for (uint32_t i = 0; i < num_pipe_; i++) {
+ src_pipes_[i].priority = i;
+ }
+
+ DLOGI("hw_rev=%x, DMA=%d RGB=%d VIG=%d", hw_res_info_.hw_revision, hw_res_info_.num_dma_pipe,
+ hw_res_info_.num_rgb_pipe, hw_res_info_.num_vig_pipe);
+
+ // Used by splash screen
+ rgb_pipes_[0].state = kPipeStateOwnedByKernel;
+ rgb_pipes_[1].state = kPipeStateOwnedByKernel;
+
+ return kErrorNone;
+}
+
+DisplayError ResManager::Deinit() {
+ return kErrorNone;
+}
+
+DisplayError ResManager::RegisterDevice(DeviceType type, const HWDeviceAttributes &attributes,
+ Handle *device) {
+ DisplayError error = kErrorNone;
+
+ HWBlockType hw_block_id = kHWBlockMax;
+ switch (type) {
+ case kPrimary:
+ if (UNLIKELY(!hw_block_ctx_[kHWPrimary].is_in_use)) {
+ hw_block_id = kHWPrimary;
+ }
+ break;
+
+ case kHDMI:
+ if (UNLIKELY(!hw_block_ctx_[kHWHDMI].is_in_use)) {
+ hw_block_id = kHWHDMI;
+ }
+ break;
+
+ case kVirtual:
+ // assume only WB2 can be used for vitrual display
+ if (UNLIKELY(!hw_block_ctx_[kHWWriteback2].is_in_use)) {
+ hw_block_id = kHWWriteback2;
+ }
+ break;
+
+ default:
+ DLOGW("RegisterDevice, invalid type %d", type);
+ return kErrorParameters;
+ }
+
+ if (UNLIKELY(hw_block_id == kHWBlockMax)) {
+ return kErrorResources;
+ }
+
+ ResManagerDevice *res_mgr_device = new ResManagerDevice();
+ if (UNLIKELY(!res_mgr_device)) {
+ return kErrorMemory;
+ }
+
+ hw_block_ctx_[hw_block_id].is_in_use = true;
+
+ res_mgr_device->device_attributes = attributes;
+ res_mgr_device->device_type = type;
+ res_mgr_device->hw_block_id = hw_block_id;
+
+ *device = res_mgr_device;
+
+ return kErrorNone;
+}
+
+DisplayError ResManager::UnregisterDevice(Handle device) {
+ ResManagerDevice *res_mgr_device = reinterpret_cast<ResManagerDevice *>(device);
+
+ Purge(device);
+ hw_block_ctx_[res_mgr_device->hw_block_id].is_in_use = false;
+ delete res_mgr_device;
+
+ return kErrorNone;
+}
+
+
+DisplayError ResManager::Start(Handle device) {
+ locker_.Lock();
+
+ ResManagerDevice *res_mgr_device = reinterpret_cast<ResManagerDevice *>(device);
+
+ if (frame_start_) {
+ return kErrorNone; // keep context locked.
+ }
+
+ // First call in the cycle
+ frame_start_ = true;
+ res_mgr_device->frame_count++;
+
+ // Release the pipes not used in the previous cycle
+ HWBlockType hw_block_id = res_mgr_device->hw_block_id;
+ for (uint32_t i = 0; i < num_pipe_; i++) {
+ if ((src_pipes_[i].hw_block_id == hw_block_id) &&
+ (src_pipes_[i].state == kPipeStateToRelease)) {
+ src_pipes_[i].state = kPipeStateIdle;
+ }
+ }
+ return kErrorNone;
+}
+
+DisplayError ResManager::Stop(Handle device) {
+ locker_.Unlock();
+
+ ResManagerDevice *res_mgr_device = reinterpret_cast<ResManagerDevice *>(device);
+
+ return kErrorNone;
+}
+
+DisplayError ResManager::Acquire(Handle device, HWLayers *hw_layers) {
+ ResManagerDevice *res_mgr_device = reinterpret_cast<ResManagerDevice *>(device);
+
+ DisplayError error = kErrorNone;
+ const struct HWLayersInfo &layer_info = hw_layers->info;
+
+ if (UNLIKELY(!layer_info.count)) {
+ return kErrorNone;
+ }
+
+ if (UNLIKELY(layer_info.count > num_pipe_)) {
+ return kErrorResources;
+ }
+
+ error = Config(res_mgr_device, hw_layers);
+ if (UNLIKELY(error != kErrorNone)) {
+ return error;
+ }
+
+ uint32_t left_index = 0;
+ bool need_scale = false;
+ HWBlockType hw_block_id = res_mgr_device->hw_block_id;
+
+ // Clear reserved marking
+ for (uint32_t i = 0; i < num_pipe_; i++) {
+ src_pipes_[i].reserved = false;
+ }
+
+ for (uint32_t i = 0; i < layer_info.count; i++) {
+ Layer &layer = layer_info.stack->layers[layer_info.index[i]];
+ bool use_non_dma_pipe = hw_layers->config[i].use_non_dma_pipe;
+
+ // Temp setting, this should be set by comp_manager
+ if (hw_block_id == kHWPrimary) {
+ use_non_dma_pipe = true;
+ }
+
+ HWPipeInfo *pipe_info = &hw_layers->config[i].left_pipe;
+
+ need_scale = IsScalingNeeded(pipe_info);
+
+ // Should have a generic macro
+ bool is_yuv = (layer.input_buffer->format >= kFormatYCbCr420Planar);
+
+ left_index = GetPipe(hw_block_id, is_yuv, need_scale, false, use_non_dma_pipe);
+ if (left_index >= num_pipe_) {
+ goto Acquire_failed;
+ }
+
+ src_pipes_[left_index].reserved = true;
+
+ pipe_info = &hw_layers->config[i].right_pipe;
+ if (pipe_info->pipe_id == 0) {
+ // assign single pipe
+ hw_layers->config[i].left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
+ src_pipes_[left_index].at_right = false;
+ continue;
+ }
+
+ need_scale = IsScalingNeeded(pipe_info);
+
+ uint32_t right_index;
+ right_index = GetPipe(hw_block_id, is_yuv, need_scale, true, use_non_dma_pipe);
+ if (right_index >= num_pipe_) {
+ goto Acquire_failed;
+ }
+
+ if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) {
+ // Swap pipe based on priority
+ Swap(left_index, right_index);
+ }
+
+ // assign dual pipes
+ hw_layers->config[i].right_pipe.pipe_id = src_pipes_[right_index].mdss_pipe_id;
+ src_pipes_[right_index].reserved = true;
+ src_pipes_[right_index].at_right = true;
+ src_pipes_[left_index].reserved = true;
+ src_pipes_[left_index].at_right = false;
+ hw_layers->config[i].left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
+ }
+
+ return kErrorNone;
+
+Acquire_failed:
+ for (uint32_t i = 0; i < num_pipe_; i++)
+ src_pipes_[i].reserved = false;
+ return kErrorResources;
+}
+
+void ResManager::PostCommit(Handle device, HWLayers *hw_layers) {
+ ResManagerDevice *res_mgr_device = reinterpret_cast<ResManagerDevice *>(device);
+ HWBlockType hw_block_id = res_mgr_device->hw_block_id;
+ uint64_t frame_count = res_mgr_device->frame_count;
+
+ DLOGV("Resource for hw_block=%d frame_count=%d", hw_block_id, frame_count);
+
+ for (uint32_t i = 0; i < num_pipe_; i++) {
+ if (src_pipes_[i].reserved) {
+ src_pipes_[i].hw_block_id = hw_block_id;
+ src_pipes_[i].state = kPipeStateAcquired;
+ src_pipes_[i].state_frame_count = frame_count;
+ DLOGV("Pipe acquired index=%d type=%d pipe_id=%x", i, src_pipes_[i].type,
+ src_pipes_[i].mdss_pipe_id);
+ } else if ((src_pipes_[i].hw_block_id == hw_block_id) &&
+ (src_pipes_[i].state == kPipeStateAcquired)) {
+ src_pipes_[i].state = kPipeStateToRelease;
+ src_pipes_[i].state_frame_count = frame_count;
+ DLOGV("Pipe to release index=%d type=%d pipe_id=%x", i, src_pipes_[i].type,
+ src_pipes_[i].mdss_pipe_id);
+ }
+ }
+
+ // handoff pipes which are used by splash screen
+ if (UNLIKELY((frame_count == 1) && (hw_block_id == kHWPrimary))) {
+ for (uint32_t i = 0; i < num_pipe_; i++) {
+ if ((src_pipes_[i].state == kPipeStateOwnedByKernel)) {
+ src_pipes_[i].state = kPipeStateToRelease;
+ src_pipes_[i].hw_block_id = kHWPrimary;
+ }
+ }
+ }
+
+ frame_start_ = false;
+}
+
+void ResManager::Purge(Handle device) {
+ SCOPE_LOCK(locker_);
+
+ ResManagerDevice *res_mgr_device = reinterpret_cast<ResManagerDevice *>(device);
+ HWBlockType hw_block_id = res_mgr_device->hw_block_id;
+
+ for (uint32_t i = 0; i < num_pipe_; i++) {
+ if (src_pipes_[i].hw_block_id == hw_block_id)
+ src_pipes_[i].state = kPipeStateIdle;
+ }
+}
+
+
+uint32_t ResManager::GetMdssPipeId(PipeType type, uint32_t index) {
+ uint32_t mdss_id = kPipeIdMax;
+ switch (type) {
+ case kPipeTypeVIG:
+ if (index < 3) {
+ mdss_id = kPipeIdVIG0 + index;
+ } else if (index == 3) {
+ mdss_id = kPipeIdVIG3;
+ } else {
+ DLOGE("vig pipe index is over the limit! %d", index);
+ }
+ break;
+ case kPipeTypeRGB:
+ if (index < 3) {
+ mdss_id = kPipeIdRGB0 + index;
+ } else if (index == 3) {
+ mdss_id = kPipeIdRGB3;
+ } else {
+ DLOGE("rgb pipe index is over the limit! %d", index);
+ }
+ break;
+ case kPipeTypeDMA:
+ if (index < 2) {
+ mdss_id = kPipeIdDMA0 + index;
+ } else {
+ DLOGE("dma pipe index is over the limit! %d", index);
+ }
+ break;
+ default:
+ DLOGE("wrong pipe type! %d", type);
+ break;
+ }
+
+ return (1 << mdss_id);
+}
+
+uint32_t ResManager::NextPipe(PipeType type, HWBlockType hw_block_id, bool at_right) {
+ uint32_t num_pipe = 0;
+ uint32_t index = kPipeIdMax;
+ SourcePipe *src_pipe = NULL;
+
+ switch (type) {
+ case kPipeTypeVIG:
+ src_pipe = vig_pipes_;
+ num_pipe = hw_res_info_.num_vig_pipe;
+ break;
+ case kPipeTypeRGB:
+ src_pipe = rgb_pipes_;
+ num_pipe = hw_res_info_.num_rgb_pipe;
+ break;
+ case kPipeTypeDMA:
+ default:
+ src_pipe = dma_pipes_;
+ num_pipe = hw_res_info_.num_dma_pipe;
+ break;
+ }
+
+ // search the pipe being used
+ for (uint32_t i = 0; i < num_pipe; i++) {
+ if (!src_pipe[i].reserved &&
+ (src_pipe[i].state == kPipeStateAcquired) &&
+ (src_pipe[i].hw_block_id == hw_block_id) &&
+ (src_pipe[i].at_right == at_right)) {
+ index = src_pipe[i].index;
+ break;
+ }
+ }
+
+ // found
+ if (index < num_pipe_) {
+ return index;
+ }
+
+ for (uint32_t i = 0; i < num_pipe; i++) {
+ if (!src_pipe[i].reserved &&
+ ((src_pipe[i].state == kPipeStateIdle) ||
+ ((src_pipe[i].state == kPipeStateAcquired) &&
+ (src_pipe[i].hw_block_id == hw_block_id)))) {
+ index = src_pipe[i].index;
+ break;
+ }
+ }
+
+ return index;
+}
+
+uint32_t ResManager::GetPipe(HWBlockType hw_block_id, bool is_yuv, bool need_scale, bool at_right,
+ bool use_non_dma_pipe) {
+ uint32_t index = kPipeIdMax;
+
+ // The default behavior is to assume RGB and VG pipes have scalars
+ if (is_yuv) {
+ return NextPipe(kPipeTypeVIG, hw_block_id, at_right);
+ } else {
+ if (!need_scale && !use_non_dma_pipe) {
+ index = NextPipe(kPipeTypeDMA, hw_block_id, at_right);
+ }
+
+ if ((index >= num_pipe_) && (!need_scale || hw_res_info_.has_non_scalar_rgb)) {
+ index = NextPipe(kPipeTypeRGB, hw_block_id, at_right);
+ }
+
+ if (index >= num_pipe_) {
+ index = NextPipe(kPipeTypeVIG, hw_block_id, at_right);
+ }
+ }
+
+ return index;
+}
+
+bool ResManager::IsScalingNeeded(const HWPipeInfo *pipe_info) {
+ const LayerRect &src_roi = pipe_info->src_roi;
+ const LayerRect &dst_roi = pipe_info->dst_roi;
+
+ return ((dst_roi.right - dst_roi.left) != (src_roi.right - src_roi.left)) ||
+ ((dst_roi.bottom - dst_roi.top) != (src_roi.bottom - src_roi.top));
+}
+
+uint32_t ResManager::GetDump(uint8_t *buffer, uint32_t length) {
+ SCOPE_LOCK(locker_);
+
+ return 0;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
new file mode 100644
index 0000000..ccd6433
--- /dev/null
+++ b/displayengine/libs/core/res_manager.h
@@ -0,0 +1,156 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __RES_MANAGER_H__
+#define __RES_MANAGER_H__
+
+#include <core/device_interface.h>
+#include <utils/locker.h>
+
+#include "hw_interface.h"
+#include "dump_impl.h"
+
+namespace sde {
+
+class ResManager : public DumpImpl {
+ public:
+ ResManager();
+ DisplayError Init(const HWResourceInfo &hw_res_info);
+ DisplayError Deinit();
+ DisplayError RegisterDevice(DeviceType type, const HWDeviceAttributes &attributes,
+ Handle *device);
+ DisplayError UnregisterDevice(Handle device);
+ DisplayError Start(Handle device);
+ DisplayError Stop(Handle device);
+ DisplayError Acquire(Handle device, HWLayers *hw_layers);
+ void PostCommit(Handle device, HWLayers *hw_layers);
+ void Purge(Handle device);
+
+ // DumpImpl method
+ virtual uint32_t GetDump(uint8_t *buffer, uint32_t length);
+
+ private:
+ enum PipeId {
+ kPipeIdVIG0,
+ kPipeIdVIG1,
+ kPipeIdVIG2,
+ kPipeIdRGB0,
+ kPipeIdRGB1,
+ kPipeIdRGB2,
+ kPipeIdDMA0,
+ kPipeIdDMA1,
+ kPipeIdVIG3,
+ kPipeIdRGB3,
+ kPipeIdMax,
+ };
+
+ enum PipeType {
+ kPipeTypeUnused,
+ kPipeTypeVIG,
+ kPipeTypeRGB,
+ kPipeTypeDMA,
+ kPipeTypeMax,
+ };
+
+ enum PipeState {
+ kPipeStateIdle, // Pipe state when it is available for reservation
+ kPipeStateAcquired, // Pipe state after successful commit
+ kPipeStateToRelease, // Pipe state that can be moved to Idle when releasefence is signaled
+ kPipeStateOwnedByKernel, // Pipe state when pipe is owned by kernel
+ };
+
+ enum {
+ kMaxSourcePipeWidth = 2048,
+ kMaxInterfaceWidth = 2048,
+ kMaxCropWidth = 5,
+ kMaxCropHeight = 5,
+ };
+
+ struct SourcePipe {
+ PipeType type;
+ uint32_t mdss_pipe_id;
+ uint32_t index;
+ PipeState state;
+ HWBlockType hw_block_id;
+ bool at_right;
+ uint64_t state_frame_count;
+ int priority;
+ bool reserved;
+
+ SourcePipe() : type(kPipeTypeUnused), mdss_pipe_id(kPipeIdMax), index(0), state(kPipeStateIdle),
+ hw_block_id(kHWBlockMax), at_right(false), state_frame_count(0), priority(0),
+ reserved(false) { }
+ };
+
+ struct ResManagerDevice {
+ HWDeviceAttributes device_attributes;
+ DeviceType device_type;
+ HWBlockType hw_block_id;
+ uint64_t frame_count;
+ int32_t session_id; // applicable for virtual display sessions only
+
+ ResManagerDevice() : hw_block_id(kHWBlockMax), frame_count(0), session_id(-1) { }
+ };
+
+ struct HWBlockContext {
+ bool is_in_use;
+ HWBlockContext() : is_in_use(false) { }
+ };
+
+ uint32_t GetMdssPipeId(PipeType pipe_type, uint32_t index);
+ uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id, bool at_right);
+ uint32_t GetPipe(HWBlockType hw_block_id, bool is_yuv, bool need_scale, bool at_right,
+ bool use_non_dma_pipe);
+ bool IsScalingNeeded(const HWPipeInfo *pipe_info);
+ DisplayError Config(ResManagerDevice *res_mgr_device, HWLayers *hw_layers);
+ bool IsValidDimension(const Layer &layer, float *width_scale, float *height_scale);
+ void CalculateCut(float *left_cut_ratio, float *top_cut_ratio, float *right_cut_ratio,
+ float *bottom_cut_ratio, const LayerTransform &transform);
+ void CalculateCropRects(LayerRect *crop, LayerRect *dst,
+ const LayerRect &scissor, const LayerTransform &transform);
+ bool IsNonIntegralSrcCrop(const LayerRect &crop);
+ void IntegerizeRect(LayerRect *dst_rect, const LayerRect &src_rect);
+
+ template <class T>
+ inline void Swap(T &a, T &b) {
+ T c(a);
+ a = b;
+ b = c;
+ }
+
+ Locker locker_;
+ HWResourceInfo hw_res_info_;
+ HWBlockContext hw_block_ctx_[kHWBlockMax];
+ SourcePipe src_pipes_[kPipeIdMax];
+ uint32_t num_pipe_;
+ SourcePipe *vig_pipes_;
+ SourcePipe *rgb_pipes_;
+ SourcePipe *dma_pipes_;
+ bool frame_start_;
+};
+
+} // namespace sde
+
+#endif // __RES_MANAGER_H__
+
diff --git a/displayengine/libs/core/strategy_default.cpp b/displayengine/libs/core/strategy_default.cpp
new file mode 100644
index 0000000..d05b9b8
--- /dev/null
+++ b/displayengine/libs/core/strategy_default.cpp
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// SDE_LOG_TAG definition must precede debug.h include.
+#define SDE_LOG_TAG kTagCore
+#define SDE_MODULE_NAME "StrategyDefault"
+#include <utils/debug.h>
+
+#include <utils/constants.h>
+
+#include "strategy_default.h"
+
+namespace sde {
+
+DisplayError StrategyDefault::GetNextStrategy(StrategyConstraints *constraints,
+ HWLayersInfo *hw_layers_info) {
+ // Mark all layers for GPU composition. Find GPU target buffer and store its index for programming
+ // the hardware.
+ LayerStack *layer_stack = hw_layers_info->stack;
+ uint32_t &hw_layer_count = hw_layers_info->count;
+
+ hw_layer_count = 0;
+ for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
+ LayerComposition &composition = layer_stack->layers[i].composition;
+ if (composition != kCompositionGPUTarget) {
+ composition = kCompositionGPU;
+ } else {
+ hw_layers_info->index[hw_layer_count++] = i;
+ }
+ }
+
+ // There can be one and only one GPU target buffer.
+ if (hw_layer_count != 1) {
+ return kErrorParameters;
+ }
+
+ hw_layers_info->flags |= kFlagGPU;
+
+ return kErrorNone;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/core/strategy_default.h b/displayengine/libs/core/strategy_default.h
new file mode 100644
index 0000000..c72bab9
--- /dev/null
+++ b/displayengine/libs/core/strategy_default.h
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __STRATEGY_DEFAULT_H__
+#define __STRATEGY_DEFAULT_H__
+
+#include <core/device_interface.h>
+#include <private/strategy_interface.h>
+
+namespace sde {
+
+class StrategyDefault : public StrategyInterface {
+ public:
+ virtual DisplayError GetNextStrategy(StrategyConstraints *constraints,
+ HWLayersInfo *hw_layers_info);
+
+ private:
+};
+
+} // namespace sde
+
+#endif // __STRATEGY_DEFAULT_H__
+
diff --git a/displayengine/libs/hwc/Android.mk b/displayengine/libs/hwc/Android.mk
new file mode 100644
index 0000000..be7e18c
--- /dev/null
+++ b/displayengine/libs/hwc/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH := $(call my-dir)
+include hardware/qcom/display/displayengine/libs/common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := hwcomposer.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"HWComposer\"
+LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL libhardware_legacy \
+ libdl libsync \
+ libbinder libmedia libskia libsdecore
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES := hwc_session.cpp \
+ hwc_sink.cpp \
+ hwc_sink_primary.cpp \
+ hwc_sink_external.cpp \
+ hwc_sink_virtual.cpp
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/hwc/hwc_logger.h b/displayengine/libs/hwc/hwc_logger.h
new file mode 100644
index 0000000..cee38e9
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_logger.h
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_LOGGER_H__
+#define __HWC_LOGGER_H__
+
+#include <cutils/log.h>
+
+#ifndef HWC_MODULE_NAME
+#define HWC_MODULE_NAME "HWComposer"
+#endif
+
+#define HWC_LOG(Macro, format, ...) Macro(HWC_MODULE_NAME ": " format, ##__VA_ARGS__)
+
+// HWC_MODULE_NAME must be defined before #include this header file in respective
+// module, else default definition is used.
+#define DLOGE(format, ...) HWC_LOG(ALOGE, format, ##__VA_ARGS__)
+#define DLOGW(format, ...) HWC_LOG(ALOGW, format, ##__VA_ARGS__)
+#define DLOGI(format, ...) HWC_LOG(ALOGI, format, ##__VA_ARGS__)
+#define DLOGV(format, ...) HWC_LOG(ALOGV, format, ##__VA_ARGS__)
+
+#endif // __HWC_LOGGER_H__
+
diff --git a/displayengine/libs/hwc/hwc_session.cpp b/displayengine/libs/hwc/hwc_session.cpp
new file mode 100644
index 0000000..51b9a80
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_session.cpp
@@ -0,0 +1,339 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <core/dump_interface.h>
+#include <utils/constants.h>
+
+// HWC_MODULE_NAME definition must precede hwc_logger.h include.
+#define HWC_MODULE_NAME "HWCSession"
+#include "hwc_logger.h"
+
+#include "hwc_session.h"
+
+static sde::HWCSession::HWCModuleMethods g_hwc_module_methods;
+
+hwc_module_t HAL_MODULE_INFO_SYM = {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 2,
+ version_minor: 0,
+ id: HWC_HARDWARE_MODULE_ID,
+ name: "QTI Hardware Composer Module",
+ author: "CodeAurora Forum",
+ methods: &g_hwc_module_methods,
+ dso: 0,
+ reserved: {0},
+ }
+};
+
+namespace sde {
+
+Locker HWCSession::locker_;
+
+HWCSession::HWCSession(const hw_module_t *module) : core_intf_(NULL), hwc_procs_(NULL) {
+ hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
+ hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_3;
+ hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module);
+ hwc_composer_device_1_t::common.close = Close;
+ hwc_composer_device_1_t::prepare = Prepare;
+ hwc_composer_device_1_t::set = Set;
+ hwc_composer_device_1_t::eventControl = EventControl;
+ hwc_composer_device_1_t::blank = Blank;
+ hwc_composer_device_1_t::query = Query;
+ hwc_composer_device_1_t::registerProcs = RegisterProcs;
+ hwc_composer_device_1_t::dump = Dump;
+ hwc_composer_device_1_t::getDisplayConfigs = GetDisplayConfigs;
+ hwc_composer_device_1_t::getDisplayAttributes = GetDisplayAttributes;
+}
+
+int HWCSession::Init() {
+ DisplayError error = CoreInterface::CreateCore(this, &core_intf_);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Display core initialization failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ int status = -EINVAL;
+
+ // Create and power on primary display
+ sink_primary_ = new HWCSinkPrimary(core_intf_, &hwc_procs_);
+ if (UNLIKELY(!sink_primary_)) {
+ CoreInterface::DestroyCore();
+ return -ENOMEM;
+ }
+
+ status = sink_primary_->Init();
+ if (UNLIKELY(status)) {
+ CoreInterface::DestroyCore();
+ delete sink_primary_;
+ return status;
+ }
+
+ status = sink_primary_->PowerOn();
+ if (UNLIKELY(status)) {
+ CoreInterface::DestroyCore();
+ sink_primary_->Deinit();
+ delete sink_primary_;
+ return status;
+ }
+
+ return 0;
+}
+
+int HWCSession::Deinit() {
+ sink_primary_->PowerOff();
+ sink_primary_->Deinit();
+ delete sink_primary_;
+
+ DisplayError error = CoreInterface::DestroyCore();
+ if (error != kErrorNone) {
+ DLOGE("Display core de-initialization failed. Error = %d", error);
+ }
+
+ return 0;
+}
+
+int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
+ if (UNLIKELY(!module || !name || !device)) {
+ DLOGE("::%s Invalid parameters.", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (LIKELY(!strcmp(name, HWC_HARDWARE_COMPOSER))) {
+ HWCSession *hwc_session = new HWCSession(module);
+ if (UNLIKELY(!hwc_session)) {
+ return -ENOMEM;
+ }
+
+ int status = hwc_session->Init();
+ if (UNLIKELY(status != 0)) {
+ delete hwc_session;
+ return status;
+ }
+
+ hwc_composer_device_1_t *composer_device = hwc_session;
+ *device = reinterpret_cast<hw_device_t *>(composer_device);
+ }
+
+ return 0;
+}
+
+int HWCSession::Close(hw_device_t *device) {
+ if (UNLIKELY(!device)) {
+ return -EINVAL;
+ }
+
+ hwc_composer_device_1_t *composer_device = reinterpret_cast<hwc_composer_device_1_t *>(device);
+ HWCSession *hwc_session = static_cast<HWCSession *>(composer_device);
+
+ hwc_session->Deinit();
+ delete hwc_session;
+
+ return 0;
+}
+
+int HWCSession::Prepare(hwc_composer_device_1 *device, size_t num_displays,
+ hwc_display_contents_1_t **displays) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!device || !displays)) {
+ return -EINVAL;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ int status = -EINVAL;
+
+ for (size_t i = 0; i < num_displays; i++) {
+ hwc_display_contents_1_t *content_list = displays[i];
+ if (UNLIKELY(!content_list || !content_list->numHwLayers)) {
+ DLOGE("::%s Invalid content list.", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ switch (i) {
+ case HWC_DISPLAY_PRIMARY:
+ status = hwc_session->sink_primary_->Prepare(content_list);
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ if (UNLIKELY(!status)) {
+ break;
+ }
+ }
+
+ return status;
+}
+
+int HWCSession::Set(hwc_composer_device_1 *device, size_t num_displays,
+ hwc_display_contents_1_t **displays) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!device || !displays)) {
+ return -EINVAL;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ int status = -EINVAL;
+
+ for (size_t i = 0; i < num_displays; i++) {
+ hwc_display_contents_1_t *content_list = displays[i];
+ if (UNLIKELY(!content_list || !content_list->numHwLayers)) {
+ DLOGE("::%s Invalid content list.", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ switch (i) {
+ case HWC_DISPLAY_PRIMARY:
+ status = hwc_session->sink_primary_->Commit(content_list);
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ if (UNLIKELY(!status)) {
+ break;
+ }
+ }
+
+ return status;
+}
+
+int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!device)) {
+ return -EINVAL;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ int status = -EINVAL;
+
+ switch (disp) {
+ case HWC_DISPLAY_PRIMARY:
+ status = hwc_session->sink_primary_->EventControl(event, enable);
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ return 0;
+}
+
+int HWCSession::Blank(hwc_composer_device_1 *device, int disp, int blank) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!device)) {
+ return -EINVAL;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ int status = -EINVAL;
+
+ switch (disp) {
+ case HWC_DISPLAY_PRIMARY:
+ status = hwc_session->sink_primary_->Blank(blank);
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+int HWCSession::Query(hwc_composer_device_1 *device, int param, int *value) {
+ if (UNLIKELY(!device || !value)) {
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
+
+void HWCSession::RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs) {
+ if (UNLIKELY(!device || !procs)) {
+ return;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ hwc_session->hwc_procs_ = procs;
+}
+
+void HWCSession::Dump(hwc_composer_device_1 *device, char *buffer, int length) {
+ SCOPE_LOCK(locker_);
+
+ if (UNLIKELY(!device || !buffer || !length)) {
+ return;
+ }
+
+ uint32_t filled = 0;
+ DumpInterface::GetDump(reinterpret_cast<uint8_t *>(buffer), length, &filled);
+}
+
+int HWCSession::GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs,
+ size_t *num_configs) {
+ if (UNLIKELY(!device || !configs || !num_configs)) {
+ return -EINVAL;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ int status = -EINVAL;
+
+ switch (disp) {
+ case HWC_DISPLAY_PRIMARY:
+ status = hwc_session->sink_primary_->GetDisplayConfigs(configs, num_configs);
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+int HWCSession::GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
+ const uint32_t *attributes, int32_t *values) {
+ if (UNLIKELY(!device || !attributes || !values)) {
+ return -EINVAL;
+ }
+
+ HWCSession *hwc_session = static_cast<HWCSession *>(device);
+ int status = -EINVAL;
+
+ switch (disp) {
+ case HWC_DISPLAY_PRIMARY:
+ status = hwc_session->sink_primary_->GetDisplayAttributes(config, attributes, values);
+ break;
+ default:
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+DisplayError HWCSession::Hotplug(const CoreEventHotplug &hotplug) {
+ return kErrorNone;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/hwc/hwc_session.h b/displayengine/libs/hwc/hwc_session.h
new file mode 100644
index 0000000..8390459
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_session.h
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_SESSION_H__
+#define __HWC_SESSION_H__
+
+#include <hardware/hwcomposer.h>
+#include <core/core_interface.h>
+#include <utils/locker.h>
+
+#include "hwc_sink_primary.h"
+
+namespace sde {
+
+class HWCSession : public hwc_composer_device_1_t, public CoreEventHandler {
+ public:
+ struct HWCModuleMethods : public hw_module_methods_t {
+ HWCModuleMethods() {
+ hw_module_methods_t::open = HWCSession::Open;
+ }
+ };
+
+ explicit HWCSession(const hw_module_t *module);
+ int Init();
+ int Deinit();
+
+ private:
+ // hwc methods
+ static int Open(const hw_module_t *module, const char* name, hw_device_t **device);
+ static int Close(hw_device_t *device);
+ static int Prepare(hwc_composer_device_1 *device, size_t num_displays,
+ hwc_display_contents_1_t **displays);
+ static int Set(hwc_composer_device_1 *device, size_t num_displays,
+ hwc_display_contents_1_t **displays);
+ static int EventControl(hwc_composer_device_1 *device, int disp, int event, int enable);
+ static int Blank(hwc_composer_device_1 *device, int disp, int blank);
+ static int Query(hwc_composer_device_1 *device, int param, int *value);
+ static void RegisterProcs(hwc_composer_device_1 *device, hwc_procs_t const *procs);
+ static void Dump(hwc_composer_device_1 *device, char *buffer, int length);
+ static int GetDisplayConfigs(hwc_composer_device_1 *device, int disp, uint32_t *configs,
+ size_t *numConfigs);
+ static int GetDisplayAttributes(hwc_composer_device_1 *device, int disp, uint32_t config,
+ const uint32_t *attributes, int32_t *values);
+
+ // CoreEventHandler methods
+ virtual DisplayError Hotplug(const CoreEventHotplug &hotplug);
+
+ static Locker locker_;
+ CoreInterface *core_intf_;
+ hwc_procs_t const *hwc_procs_;
+ HWCSinkPrimary *sink_primary_;
+};
+
+} // namespace sde
+
+#endif // __HWC_SESSION_H__
+
diff --git a/displayengine/libs/hwc/hwc_sink.cpp b/displayengine/libs/hwc/hwc_sink.cpp
new file mode 100644
index 0000000..e5b07f5
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink.cpp
@@ -0,0 +1,405 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <errno.h>
+#include <gralloc_priv.h>
+#include <utils/constants.h>
+
+// HWC_MODULE_NAME definition must precede hwc_logger.h include.
+#define HWC_MODULE_NAME "HWCSink"
+#include "hwc_logger.h"
+
+#include "hwc_sink.h"
+
+namespace sde {
+
+HWCSink::HWCSink(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DeviceType type, int id)
+ : core_intf_(core_intf), hwc_procs_(hwc_procs), type_(type), id_(id), device_intf_(NULL) {
+}
+
+int HWCSink::Init() {
+ DisplayError error = core_intf_->CreateDevice(type_, this, &device_intf_);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Display device create failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int HWCSink::Deinit() {
+ DisplayError error = core_intf_->DestroyDevice(device_intf_);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Display device destroy failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ if (LIKELY(layer_stack_.raw)) {
+ delete[] layer_stack_.raw;
+ }
+
+ return 0;
+}
+
+int HWCSink::EventControl(int event, int enable) {
+ DisplayError error = kErrorNone;
+
+ switch (event) {
+ case HWC_EVENT_VSYNC:
+ error = device_intf_->SetVSyncState(enable);
+ break;
+
+ default:
+ DLOGE("Unsupported event control type : %d", event);
+ }
+
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("EventControl failed. event = %d, enable = %d, error = %d", event, enable, error);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int HWCSink::Blank(int blank) {
+ DLOGI("Blank : %d, display : %d", blank, id_);
+ DeviceState state = blank ? kStateOff : kStateOn;
+ return SetState(state);
+}
+
+int HWCSink::GetDisplayConfigs(uint32_t *configs, size_t *num_configs) {
+ if (*num_configs > 0) {
+ configs[0] = 0;
+ *num_configs = 1;
+ }
+
+ return 0;
+}
+
+int HWCSink::GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values) {
+ DisplayError error = kErrorNone;
+
+ DeviceConfigVariableInfo variable_config;
+ error = device_intf_->GetConfig(&variable_config, 0);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("GetConfig variable info failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
+ switch (attributes[i]) {
+ case HWC_DISPLAY_VSYNC_PERIOD:
+ values[i] = variable_config.vsync_period_ns;
+ break;
+ case HWC_DISPLAY_WIDTH:
+ values[i] = variable_config.x_pixels;
+ break;
+ case HWC_DISPLAY_HEIGHT:
+ values[i] = variable_config.y_pixels;
+ break;
+ case HWC_DISPLAY_DPI_X:
+ values[i] = INT32(variable_config.x_dpi * 1000.0f);
+ break;
+ case HWC_DISPLAY_DPI_Y:
+ values[i] = INT32(variable_config.y_dpi * 1000.0f);
+ break;
+ default:
+ DLOGE("Spurious attribute type %d", attributes[i]);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int HWCSink::SetState(DeviceState state) {
+ DisplayError error = device_intf_->SetDeviceState(state);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Set state failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+DisplayError HWCSink::VSync(const DeviceEventVSync &vsync) {
+ if (*hwc_procs_) {
+ (*hwc_procs_)->vsync(*hwc_procs_, id_, vsync.timestamp);
+ }
+
+ return kErrorNone;
+}
+
+DisplayError HWCSink::Refresh() {
+ if (*hwc_procs_) {
+ (*hwc_procs_)->invalidate(*hwc_procs_);
+ }
+
+ return kErrorNone;
+}
+
+int HWCSink::AllocateLayerStack(hwc_display_contents_1_t *content_list) {
+ size_t num_hw_layers = content_list->numHwLayers;
+
+ // Allocate memory for a) total number of layers b) buffer handle for each layer c) number of
+ // visible rectangles in each layer d) dirty rectangle for each layer
+ size_t required_size = num_hw_layers * (sizeof(Layer) + sizeof(LayerBuffer));
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ // visible rectangles + 1 dirty rectangle
+ size_t num_rects = content_list->hwLayers[i].visibleRegionScreen.numRects + 1;
+ required_size += num_rects * sizeof(LayerRect);
+ }
+
+ // Layer array may be large enough to hold current number of layers.
+ // If not, re-allocate it now.
+ if (UNLIKELY(layer_stack_.size < required_size)) {
+ if (LIKELY(layer_stack_.raw)) {
+ delete[] layer_stack_.raw;
+ layer_stack_.size = 0;
+ }
+
+ // Allocate in multiple of kSizeSteps.
+ required_size = ROUND_UP(required_size, layer_stack_.kSizeSteps);
+
+ layer_stack_.raw = new uint8_t[required_size];
+ if (UNLIKELY(!layer_stack_.raw)) {
+ return -ENOMEM;
+ }
+
+ layer_stack_.size = required_size;
+ }
+
+ // Assign memory addresses now.
+ uint8_t *current_address = layer_stack_.raw;
+
+ // Layer array address
+ layer_stack_.layers = reinterpret_cast<Layer *>(current_address);
+ layer_stack_.layer_count = static_cast<uint32_t>(num_hw_layers);
+ current_address += num_hw_layers * sizeof(Layer);
+
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ Layer &layer = layer_stack_.layers[i];
+
+ // Layer buffer handle address
+ layer.input_buffer = reinterpret_cast<LayerBuffer *>(current_address);
+ current_address += sizeof(LayerBuffer);
+
+ // Visible rectangle address
+ layer.visible_regions.rect = reinterpret_cast<LayerRect *>(current_address);
+ layer.visible_regions.count = static_cast<uint32_t>(hwc_layer.visibleRegionScreen.numRects);
+ current_address += hwc_layer.visibleRegionScreen.numRects * sizeof(LayerRect);
+
+ // Dirty rectangle address
+ layer.dirty_regions.rect = reinterpret_cast<LayerRect *>(current_address);
+ layer.dirty_regions.count = 1;
+ current_address += sizeof(LayerRect);
+ }
+
+ return 0;
+}
+
+int HWCSink::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
+ size_t num_hw_layers = content_list->numHwLayers;
+ if (UNLIKELY(num_hw_layers <= 1)) {
+ return 0;
+ }
+
+ // Configure each layer
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ const private_handle_t *pvt_handle = static_cast<const private_handle_t *>(hwc_layer.handle);
+
+ Layer &layer = layer_stack_.layers[i];
+ LayerBuffer *layer_buffer = layer.input_buffer;
+
+ if (pvt_handle) {
+ if (UNLIKELY(SetFormat(&layer_buffer->format, pvt_handle->format))) {
+ return -EINVAL;
+ }
+
+ layer_buffer->width = pvt_handle->width;
+ layer_buffer->height = pvt_handle->height;
+ layer_buffer->planes[0].fd = pvt_handle->fd;
+ layer_buffer->planes[0].offset = pvt_handle->offset;
+ layer_buffer->planes[0].stride = pvt_handle->width;
+ }
+
+ SetRect(&layer.dst_rect, hwc_layer.displayFrame);
+ SetRect(&layer.src_rect, hwc_layer.sourceCropf);
+ for (size_t j = 0; j < hwc_layer.visibleRegionScreen.numRects; j++) {
+ SetRect(&layer.visible_regions.rect[j], hwc_layer.visibleRegionScreen.rects[j]);
+ }
+ SetRect(&layer.dirty_regions.rect[0], hwc_layer.dirtyRect);
+
+ SetComposition(&layer.composition, hwc_layer.compositionType);
+ SetBlending(&layer.blending, hwc_layer.blending);
+
+ LayerTransform &layer_transform = layer.transform;
+ uint32_t &hwc_transform = hwc_layer.transform;
+ layer_transform.flip_horizontal = ((hwc_transform & HWC_TRANSFORM_FLIP_H) > 0);
+ layer_transform.flip_vertical = ((hwc_transform & HWC_TRANSFORM_FLIP_V) > 0);
+ layer_transform.rotation = ((hwc_transform& HWC_TRANSFORM_ROT_90) ? 90.0f : 0.0f);
+
+ layer.plane_alpha = hwc_layer.planeAlpha;
+ layer.flags.skip = ((hwc_layer.flags & HWC_SKIP_LAYER) > 0);
+ }
+
+ // Configure layer stack
+ layer_stack_.flags.geometry_changed = ((content_list->flags & HWC_GEOMETRY_CHANGED) > 0);
+
+ DisplayError error = device_intf_->Prepare(&layer_stack_);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Prepare failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ Layer &layer = layer_stack_.layers[i];
+ SetComposition(&hwc_layer.compositionType, layer.composition);
+ }
+
+ return 0;
+}
+
+int HWCSink::CommitLayerStack(hwc_display_contents_1_t *content_list) {
+ size_t num_hw_layers = content_list->numHwLayers;
+ if (UNLIKELY(num_hw_layers <= 1)) {
+ return 0;
+ }
+
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
+
+ layer_buffer->acquire_fence_fd = hwc_layer.acquireFenceFd;
+ }
+
+ DisplayError error = device_intf_->Commit(&layer_stack_);
+ if (UNLIKELY(error != kErrorNone)) {
+ DLOGE("Commit failed. Error = %d", error);
+ return -EINVAL;
+ }
+
+ for (size_t i = 0; i < num_hw_layers; i++) {
+ hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
+ Layer &layer = layer_stack_.layers[i];
+ LayerBuffer *layer_buffer = layer_stack_.layers[i].input_buffer;
+
+ if (layer.composition == kCompositionSDE || layer.composition == kCompositionGPUTarget) {
+ hwc_layer.releaseFenceFd = layer_buffer->release_fence_fd;
+ }
+
+ if (hwc_layer.acquireFenceFd >= 0) {
+ close(hwc_layer.acquireFenceFd);
+ }
+ }
+
+ return 0;
+}
+
+void HWCSink::SetRect(LayerRect *target, const hwc_rect_t &source) {
+ target->left = FLOAT(source.left);
+ target->top = FLOAT(source.top);
+ target->right = FLOAT(source.right);
+ target->bottom = FLOAT(source.bottom);
+}
+
+void HWCSink::SetRect(LayerRect *target, const hwc_frect_t &source) {
+ target->left = source.left;
+ target->top = source.top;
+ target->right = source.right;
+ target->bottom = source.bottom;
+}
+
+void HWCSink::SetComposition(LayerComposition *target, const int32_t &source) {
+ switch (source) {
+ case HWC_FRAMEBUFFER_TARGET:
+ *target = kCompositionGPUTarget;
+ break;
+ default:
+ *target = kCompositionSDE;
+ break;
+ }
+}
+
+void HWCSink::SetComposition(int32_t *target, const LayerComposition &source) {
+ switch (source) {
+ case kCompositionGPUTarget:
+ *target = HWC_FRAMEBUFFER_TARGET;
+ break;
+ case kCompositionSDE:
+ *target = HWC_OVERLAY;
+ break;
+ default:
+ *target = HWC_FRAMEBUFFER;
+ break;
+ }
+}
+
+void HWCSink::SetBlending(LayerBlending *target, const int32_t &source) {
+ switch (source) {
+ case HWC_BLENDING_PREMULT:
+ *target = kBlendingPremultiplied;
+ break;
+ case HWC_BLENDING_COVERAGE:
+ *target = kBlendingCoverage;
+ break;
+ default:
+ *target = kBlendingNone;
+ break;
+ }
+}
+
+int HWCSink::SetFormat(LayerBufferFormat *target, const int &source) {
+ switch (source) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ *target = kFormatRGBA8888;
+ break;
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ *target = kFormatBGRA8888;
+ break;
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ *target = kFormatRGBX8888;
+ break;
+ case HAL_PIXEL_FORMAT_BGRX_8888:
+ *target = kFormatBGRX8888;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ *target = kFormatRGB888;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ *target = kFormatRGB565;
+ break;
+ default:
+ DLOGE("Unsupported format type %d", source);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/hwc/hwc_sink.h b/displayengine/libs/hwc/hwc_sink.h
new file mode 100644
index 0000000..340aabd
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink.h
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_SINK_H__
+#define __HWC_SINK_H__
+
+#include <hardware/hwcomposer.h>
+#include <core/core_interface.h>
+
+namespace sde {
+
+class HWCSink : public DeviceEventHandler {
+ public:
+ virtual int Init();
+ virtual int Deinit();
+ virtual int Prepare(hwc_display_contents_1_t *content_list) = 0;
+ virtual int Commit(hwc_display_contents_1_t *content_list) = 0;
+ virtual int EventControl(int event, int enable);
+ virtual int Blank(int blank);
+ virtual int GetDisplayConfigs(uint32_t *configs, size_t *num_configs);
+ virtual int GetDisplayAttributes(uint32_t config, const uint32_t *attributes, int32_t *values);
+ int SetState(DeviceState state);
+
+ protected:
+ HWCSink(CoreInterface *core_intf, hwc_procs_t const **hwc_procs, DeviceType type, int id);
+ virtual ~HWCSink() { }
+
+ // DeviceEventHandler methods
+ virtual DisplayError VSync(const DeviceEventVSync &vsync);
+ virtual DisplayError Refresh();
+
+ virtual int AllocateLayerStack(hwc_display_contents_1_t *content_list);
+ virtual int PrepareLayerStack(hwc_display_contents_1_t *content_list);
+ virtual int CommitLayerStack(hwc_display_contents_1_t *content_list);
+ inline void SetRect(LayerRect *target, const hwc_rect_t &source);
+ inline void SetRect(LayerRect *target, const hwc_frect_t &source);
+ inline void SetComposition(LayerComposition *target, const int32_t &source);
+ inline void SetComposition(int32_t *target, const LayerComposition &source);
+ inline void SetBlending(LayerBlending *target, const int32_t &source);
+ inline int SetFormat(LayerBufferFormat *target, const int &source);
+
+ // Structure to track memory allocation for layer stack (layers, rectangles) object.
+ struct LayerStackMemory : LayerStack {
+ static const size_t kSizeSteps = 4096; // Default memory allocation.
+ uint8_t *raw; // Pointer to byte array.
+ size_t size; // Current number of allocated bytes.
+ } layer_stack_;
+
+ CoreInterface *core_intf_;
+ hwc_procs_t const **hwc_procs_;
+ DeviceType type_;
+ int id_;
+ DeviceInterface *device_intf_;
+};
+
+} // namespace sde
+
+#endif // __HWC_SINK_H__
+
diff --git a/displayengine/libs/hwc/hwc_sink_external.cpp b/displayengine/libs/hwc/hwc_sink_external.cpp
new file mode 100644
index 0000000..d506194
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink_external.cpp
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/constants.h>
+
+// HWC_MODULE_NAME definition must precede hwc_logger.h include.
+#define HWC_MODULE_NAME "HWCSinkExternal"
+#include "hwc_logger.h"
+
+#include "hwc_sink_external.h"
+
+namespace sde {
+
+HWCSinkExternal::HWCSinkExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
+ : HWCSink(core_intf, hwc_procs, kHDMI, HWC_DISPLAY_EXTERNAL) {
+}
+
+int HWCSinkExternal::Init() {
+ return 0;
+}
+
+int HWCSinkExternal::Deinit() {
+ return 0;
+}
+
+int HWCSinkExternal::Prepare(hwc_display_contents_1_t *content_list) {
+ return 0;
+}
+
+int HWCSinkExternal::Commit(hwc_display_contents_1_t *content_list) {
+ return 0;
+}
+
+int HWCSinkExternal::PowerOn() {
+ return 0;
+}
+
+int HWCSinkExternal::PowerOff() {
+ return 0;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/hwc/hwc_sink_external.h b/displayengine/libs/hwc/hwc_sink_external.h
new file mode 100644
index 0000000..c0eab7f
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink_external.h
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_SINK_EXTERNAL_H__
+#define __HWC_SINK_EXTERNAL_H__
+
+#include "hwc_sink.h"
+
+namespace sde {
+
+class HWCSinkExternal : public HWCSink {
+ public:
+ explicit HWCSinkExternal(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+ virtual int Init();
+ virtual int Deinit();
+ virtual int Prepare(hwc_display_contents_1_t *content_list);
+ virtual int Commit(hwc_display_contents_1_t *content_list);
+ virtual int PowerOn();
+ virtual int PowerOff();
+};
+
+} // namespace sde
+
+#endif // __HWC_SINK_EXTERNAL_H__
+
diff --git a/displayengine/libs/hwc/hwc_sink_primary.cpp b/displayengine/libs/hwc/hwc_sink_primary.cpp
new file mode 100644
index 0000000..a9b74bf
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink_primary.cpp
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/constants.h>
+
+// HWC_MODULE_NAME definition must precede hwc_logger.h include.
+#define HWC_MODULE_NAME "HWCSinkPrimary"
+#include "hwc_logger.h"
+
+#include "hwc_sink_primary.h"
+
+namespace sde {
+
+HWCSinkPrimary::HWCSinkPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
+ : HWCSink(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY) {
+}
+
+int HWCSinkPrimary::Init() {
+ return HWCSink::Init();
+}
+
+int HWCSinkPrimary::Deinit() {
+ return HWCSink::Deinit();
+}
+
+int HWCSinkPrimary::Prepare(hwc_display_contents_1_t *content_list) {
+ int status = 0;
+
+ status = AllocateLayerStack(content_list);
+ if (UNLIKELY(status)) {
+ return status;
+ }
+
+ status = PrepareLayerStack(content_list);
+ if (UNLIKELY(status)) {
+ return status;
+ }
+
+ return 0;
+}
+
+int HWCSinkPrimary::Commit(hwc_display_contents_1_t *content_list) {
+ int status = 0;
+
+ status = HWCSink::CommitLayerStack(content_list);
+ if (UNLIKELY(status)) {
+ return status;
+ }
+
+ content_list->retireFenceFd = layer_stack_.retire_fence_fd;
+
+ return 0;
+}
+
+int HWCSinkPrimary::PowerOn() {
+ return SetState(kStateOn);
+}
+
+int HWCSinkPrimary::PowerOff() {
+ return SetState(kStateOff);
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/hwc/hwc_sink_primary.h b/displayengine/libs/hwc/hwc_sink_primary.h
new file mode 100644
index 0000000..f16c5a6
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink_primary.h
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_SINK_PRIMARY_H__
+#define __HWC_SINK_PRIMARY_H__
+
+#include "hwc_sink.h"
+
+namespace sde {
+
+class HWCSinkPrimary : public HWCSink {
+ public:
+ explicit HWCSinkPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+ virtual int Init();
+ virtual int Deinit();
+ virtual int Prepare(hwc_display_contents_1_t *content_list);
+ virtual int Commit(hwc_display_contents_1_t *content_list);
+ virtual int PowerOn();
+ virtual int PowerOff();
+};
+
+} // namespace sde
+
+#endif // __HWC_SINK_PRIMARY_H__
+
diff --git a/displayengine/libs/hwc/hwc_sink_virtual.cpp b/displayengine/libs/hwc/hwc_sink_virtual.cpp
new file mode 100644
index 0000000..49334a3
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink_virtual.cpp
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/constants.h>
+
+// HWC_MODULE_NAME definition must precede hwc_logger.h include.
+#define HWC_MODULE_NAME "HWCSinkVirtual"
+#include "hwc_logger.h"
+
+#include "hwc_sink_virtual.h"
+
+namespace sde {
+
+HWCSinkVirtual::HWCSinkVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
+ : HWCSink(core_intf, hwc_procs, kVirtual, HWC_DISPLAY_VIRTUAL) {
+}
+
+int HWCSinkVirtual::Init() {
+ return 0;
+}
+
+int HWCSinkVirtual::Deinit() {
+ return 0;
+}
+
+int HWCSinkVirtual::Prepare(hwc_display_contents_1_t *content_list) {
+ return 0;
+}
+
+int HWCSinkVirtual::Commit(hwc_display_contents_1_t *content_list) {
+ return 0;
+}
+
+int HWCSinkVirtual::PowerOn() {
+ return 0;
+}
+
+int HWCSinkVirtual::PowerOff() {
+ return 0;
+}
+
+} // namespace sde
+
diff --git a/displayengine/libs/hwc/hwc_sink_virtual.h b/displayengine/libs/hwc/hwc_sink_virtual.h
new file mode 100644
index 0000000..381c1e3
--- /dev/null
+++ b/displayengine/libs/hwc/hwc_sink_virtual.h
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HWC_SINK_VIRTUAL_H__
+#define __HWC_SINK_VIRTUAL_H__
+
+#include "hwc_sink.h"
+
+namespace sde {
+
+class HWCSinkVirtual : public HWCSink {
+ public:
+ explicit HWCSinkVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs);
+ virtual int Init();
+ virtual int Deinit();
+ virtual int Prepare(hwc_display_contents_1_t *content_list);
+ virtual int Commit(hwc_display_contents_1_t *content_list);
+ virtual int PowerOn();
+ virtual int PowerOff();
+};
+
+} // namespace sde
+
+#endif // __HWC_SINK_VIRTUAL_H__
+
diff --git a/displayengine/libs/utils/Android.mk b/displayengine/libs/utils/Android.mk
new file mode 100644
index 0000000..d5ba512
--- /dev/null
+++ b/displayengine/libs/utils/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+include hardware/qcom/display/displayengine/libs/common.mk
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libsdeutils
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
+LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"SDE\"
+LOCAL_SHARED_LIBRARIES := $(common_libs)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES := debug_android.cpp
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/utils/debug_android.cpp b/displayengine/libs/utils/debug_android.cpp
new file mode 100644
index 0000000..09b32fe
--- /dev/null
+++ b/displayengine/libs/utils/debug_android.cpp
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <utils/debug.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+namespace sde {
+
+Debug Debug::debug_;
+
+Debug::Debug() : virtual_driver_(false) {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get("displaycore.virtualdriver", property, NULL) > 0) {
+ virtual_driver_ = (atoi(property) == 1);
+ }
+}
+
+void Debug::Error(const LogTag & /*tag*/, const char *format, ...) {
+ va_list list;
+ va_start(list, format);
+ __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, list);
+}
+
+void Debug::Warning(const LogTag & /*tag*/, const char *format, ...) {
+ va_list list;
+ va_start(list, format);
+ __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, list);
+}
+
+void Debug::Info(const LogTag & /*tag*/, const char *format, ...) {
+ va_list list;
+ va_start(list, format);
+ __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, list);
+}
+
+void Debug::Verbose(const LogTag & /*tag*/, const char *format, ...) {
+ va_list list;
+ va_start(list, format);
+ __android_log_vprint(ANDROID_LOG_VERBOSE, LOG_TAG, format, list);
+}
+
+} // namespace sde
+
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 421f531..da18c7b 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -584,7 +584,6 @@
struct blitReq list1;
memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
list1.count = 1;
- int rel_fen_fd = -1;
int my_tmp_get_fence = -1;
list1.sync.acq_fen_fd = ctx->acqFence;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a7eb561..0a7f940 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -113,11 +113,12 @@
}
}
-/* Based on certain conditions, isPaddingRound will be set
+/* Based on certain conditions, isDMAStateChanging will be set
* to make this function self-contained */
static void setDMAState(hwc_context_t *ctx, int numDisplays,
hwc_display_contents_1_t** displays) {
+ ctx->isDMAStateChanging = false;
if(ctx->mRotMgr->getNumActiveSessions() == 0)
Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
@@ -142,7 +143,7 @@
dpy)) {
if(ctx->mOverlay->isPipeTypeAttached(
overlay::utils::OV_MDP_PIPE_DMA))
- ctx->isPaddingRound = true;
+ ctx->isDMAStateChanging = true;
}
Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
}
@@ -160,7 +161,7 @@
if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
if(ctx->mOverlay->isPipeTypeAttached(
overlay::utils::OV_MDP_PIPE_DMA)) {
- ctx->isPaddingRound = true;
+ ctx->isDMAStateChanging = true;
}
Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
}
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 67cca88..38c0810 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -603,6 +603,12 @@
return fd;
}
+ //Clear the transparent or left out region on the render buffer
+ hwc_rect_t clearRegion = {0,0,0,0};
+ LayerProp *layerProp = ctx->layerProp[0];
+ if(CBUtils::getuiClearRegion(list, clearRegion, layerProp))
+ clear(renderBuffer, clearRegion);
+
int copybitLayerCount = 0;
for(int j = 0; j < ptorInfo->count; j++) {
int ovlapIndex = ptorInfo->layerIndex[j];
@@ -639,9 +645,27 @@
close(list->hwLayers[i].acquireFenceFd);
list->hwLayers[i].acquireFenceFd = -1;
}
+ /*
+ * Find the intersection of layer display frame with PTOR layer
+ * with respect to screen co-ordinates
+ *
+ * Calculated the destination rect by transforming the overlapping
+ * region of layer display frame with respect to PTOR display frame
+ *
+ * Transform the destination rect on to render buffer
+ * */
+ hwc_rect_t destRect = getIntersection(overlap, layer->displayFrame);
+ destRect.left = destRect.left - overlap.left +
+ ptorInfo->displayFrame[j].left;
+ destRect.right = destRect.right- overlap.left +
+ ptorInfo->displayFrame[j].left;
+ destRect.top = destRect.top - overlap.top +
+ ptorInfo->displayFrame[j].top;
+ destRect.bottom = destRect.bottom - overlap.top +
+ ptorInfo->displayFrame[j].top;
- int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap,
- ptorInfo->displayFrame[j]);
+ int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer,
+ overlap, destRect);
copybitLayerCount++;
if(retVal < 0) {
ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 5961076..aa7783c 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -114,7 +114,8 @@
char property[PROPERTY_VALUE_MAX] = {0};
sEnabled = false;
- if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
+ if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
+ (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
sEnabled = true;
@@ -480,7 +481,15 @@
__FUNCTION__,mDpy);
ret = false;
}
+ } else if (ctx->isDMAStateChanging) {
+ // Bail out if a padding round has been invoked in order to switch DMA
+ // state to block mode. We need this to cater for the case when a layer
+ // requires rotation in the current frame.
+ ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
+ __FUNCTION__);
+ return false;
}
+
return ret;
}
@@ -523,7 +532,8 @@
}
/* deduct any opaque region from visibleRect */
- if (layer->blending == HWC_BLENDING_NONE)
+ if (layer->blending == HWC_BLENDING_NONE &&
+ layer->planeAlpha == 0xFF)
visibleRect = deductRect(visibleRect, res);
}
}
@@ -629,7 +639,8 @@
return false;
}
- if (layer->blending == HWC_BLENDING_NONE) {
+ if (layer->blending == HWC_BLENDING_NONE &&
+ layer->planeAlpha == 0xFF) {
visibleRectL = deductRect(visibleRectL, l_res);
visibleRectR = deductRect(visibleRectR, r_res);
}
@@ -2652,7 +2663,8 @@
ctx->mLayerRotMap[mDpy]->add(layer, *rot);
//If the video is using a single pipe, enable BWC
if(rDest == OV_INVALID) {
- BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
+ BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
+ mdpFlags);
}
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8e8066e..398995a 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -41,6 +41,7 @@
using namespace qService;
using namespace qhwc;
using namespace overlay;
+using namespace qdutils;
namespace qClient {
@@ -184,7 +185,7 @@
handle_resume(ctx, dpy);
}
} else {
- ALOGE("%s: Invalid dpy", __FUNCTION__, dpy);
+ ALOGE("%s: Invalid dpy %d", __FUNCTION__, dpy);
return;
}
}
@@ -251,6 +252,17 @@
MDPComp::setMaxPipesPerMixer(value);
}
+static void toggleBWC(hwc_context_t* ctx, const Parcel* inParcel) {
+ uint32_t enable = (uint32_t)inParcel->readInt32();
+ if(MDPVersion::getInstance().supportsBWC()) {
+ Locker::Autolock _sl(ctx->mDrawLock);
+ ctx->mBWCEnabled = (bool) enable;
+ ALOGI("%s: Set BWC to %d", __FUNCTION__, enable);
+ } else {
+ ALOGI("%s: Target doesn't support BWC", __FUNCTION__);
+ }
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -299,6 +311,9 @@
case IQService::SET_MAX_PIPES_PER_MIXER:
setMaxPipesPerMixer(mHwcContext, inParcel);
break;
+ case IQService::TOGGLE_BWC:
+ toggleBWC(mHwcContext, inParcel);
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index b091ae2..916fbc7 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -296,6 +296,7 @@
ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
ctx->mOverlay = overlay::Overlay::getInstance();
ctx->mRotMgr = RotMgr::getInstance();
+ ctx->mBWCEnabled = qdutils::MDPVersion::getInstance().supportsBWC();
//default_app_buffer for ferrum
if (ctx->mMDP.version == qdutils::MDP_V3_0_5) {
@@ -1382,7 +1383,8 @@
//see if there is no blending required.
//If it is opaque see if we can substract this region from below
//layers.
- if(list->hwLayers[i].blending == HWC_BLENDING_NONE) {
+ if(list->hwLayers[i].blending == HWC_BLENDING_NONE &&
+ list->hwLayers[i].planeAlpha == 0xFF) {
int j= i-1;
hwc_rect_t& topframe =
(hwc_rect_t&)list->hwLayers[i].displayFrame;
@@ -1979,9 +1981,8 @@
*rot = ctx->mRotMgr->getNext();
if(*rot == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
- // BWC is not tested for other formats So enable it only for YUV format
- if(!dpy && isYuvBuffer(hnd))
- BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
+ BwcPM::setBwc(ctx, dpy, hnd, crop, dst, transform, downscale,
+ mdpFlags);
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
ALOGE("%s: configRotator failed!", __FUNCTION__);
@@ -2226,9 +2227,8 @@
(*rot) = ctx->mRotMgr->getNext();
if((*rot) == NULL) return -1;
ctx->mLayerRotMap[dpy]->add(layer, *rot);
- // BWC is not tested for other formats So enable it only for YUV format
- if(!dpy && isYuvBuffer(hnd))
- BwcPM::setBwc(crop, dst, transform, downscale, mdpFlagsL);
+ BwcPM::setBwc(ctx, dpy, hnd, crop, dst, transform, downscale,
+ mdpFlagsL);
//Configure rotator for pre-rotation
if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
ALOGE("%s: configRotator failed!", __FUNCTION__);
@@ -2482,17 +2482,25 @@
return (eqBounds == 3);
}
-void BwcPM::setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst,
+void BwcPM::setBwc(const hwc_context_t *ctx, const int& dpy,
+ const private_handle_t *hnd,
+ const hwc_rect_t& crop, const hwc_rect_t& dst,
const int& transform,const int& downscale,
ovutils::eMdpFlags& mdpFlags) {
- //BWC not supported with rot-downscale
- if(downscale) return;
-
//Target doesnt support Bwc
qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
- if(!mdpHw.supportsBWC()) {
+ if(not mdpHw.supportsBWC()) {
return;
}
+ //Disabled at runtime
+ if(not ctx->mBWCEnabled) return;
+ //BWC not supported with rot-downscale
+ if(downscale) return;
+ //Not enabled for secondary displays
+ if(dpy) return;
+ //Not enabled for non-video buffers
+ if(not isYuvBuffer(hnd)) return;
+
int src_w = crop.right - crop.left;
int src_h = crop.bottom - crop.top;
int dst_w = dst.right - dst.left;
@@ -2512,10 +2520,6 @@
vertDeci);
if(horzDeci || vertDeci) return;
}
- //Property
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.disable.bwc", value, "0");
- if(atoi(value)) return;
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
}
@@ -2711,6 +2715,12 @@
// Handles online events when HDMI is the primary display. In particular,
// online events for hdmi connected before AND after boot up and HWC init.
void handle_online(hwc_context_t* ctx, int dpy) {
+ //On 8994 due to hardware limitations, we disable bwc completely when HDMI
+ //intf is active
+ if(qdutils::MDPVersion::getInstance().is8994() and
+ qdutils::MDPVersion::getInstance().supportsBWC()) {
+ ctx->mBWCEnabled = false;
+ }
// Close the current fd if it was opened earlier on when HWC
// was initialized.
if (ctx->dpyAttr[dpy].fd >= 0) {
@@ -2741,6 +2751,12 @@
resetDisplayInfo(ctx, dpy);
ctx->dpyAttr[dpy].connected = false;
ctx->dpyAttr[dpy].isActive = false;
+ //On 8994 due to hardware limitations, we enable bwc only when HDMI
+ //intf is inactive
+ if(qdutils::MDPVersion::getInstance().is8994() and
+ qdutils::MDPVersion::getInstance().supportsBWC()) {
+ ctx->mBWCEnabled = true;
+ }
}
};//namespace qhwc
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 7597457..741527c 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -174,7 +174,9 @@
};
struct BwcPM {
- static void setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst,
+ static void setBwc(const hwc_context_t *ctx, const int& dpy,
+ const private_handle_t *hnd,
+ const hwc_rect_t& crop, const hwc_rect_t& dst,
const int& transform, const int& downscale,
ovutils::eMdpFlags& mdpFlags);
};
@@ -604,6 +606,8 @@
mutable Locker mDrawLock;
//Drawing round when we use GPU
bool isPaddingRound;
+ // Used to mark composition cycle when DMA state change is required
+ bool isDMAStateChanging;
// External Orientation
int mExtOrientation;
//Flags the transition of a video session
@@ -633,6 +637,8 @@
// This denotes the tolerance between video layer and external display
// aspect ratio
float mAspectRatioToleranceLevel;
+ // Runtime switch for BWC for targets that support it
+ bool mBWCEnabled;
};
namespace qhwc {
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 7b97c6c..722916a 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -88,9 +88,10 @@
thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0);
}
- if (thermalLevel >= MAX_THERMAL_LEVEL)
+ if (thermalLevel >= MAX_THERMAL_LEVEL) {
+ ALOGD("%s: dpy:%d thermal_level=%"PRIu64"",__FUNCTION__,dpy,thermalLevel);
ctx->mThermalBurstMode = true;
- else
+ } else
ctx->mThermalBurstMode = false;
}
diff --git a/libqdutils/cb_utils.cpp b/libqdutils/cb_utils.cpp
index a2b706c..ef66ac6 100644
--- a/libqdutils/cb_utils.cpp
+++ b/libqdutils/cb_utils.cpp
@@ -51,7 +51,8 @@
if(cb_swap_rect::getInstance().checkSwapRectFeature_on() == true){
wormholeRegion.set(0,0);
for(size_t i = 0 ; i < last; i++) {
- if((list->hwLayers[i].blending == HWC_BLENDING_NONE) ||
+ if(((list->hwLayers[i].blending == HWC_BLENDING_NONE) &&
+ (list->hwLayers[i].planeAlpha == 0xFF)) ||
!(layerProp[i].mFlags & HWC_COPYBIT) ||
(list->hwLayers[i].flags & HWC_SKIP_HWC_COMPOSITION))
continue ;
@@ -65,6 +66,7 @@
// need to take care only in per pixel blending.
// Restrict calculation only for copybit layers.
if((list->hwLayers[i].blending != HWC_BLENDING_NONE) ||
+ (list->hwLayers[i].planeAlpha != 0xFF) ||
!(layerProp[i].mFlags & HWC_COPYBIT))
continue ;
hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
diff --git a/libqdutils/idle_invalidator.cpp b/libqdutils/idle_invalidator.cpp
index 5850ce5..b8db0bf 100644
--- a/libqdutils/idle_invalidator.cpp
+++ b/libqdutils/idle_invalidator.cpp
@@ -32,6 +32,7 @@
#include <poll.h>
#include <string.h>
#include <fcntl.h>
+#include <cutils/properties.h>
#define II_DEBUG 0
#define IDLE_NOTIFY_PATH "/sys/devices/virtual/graphics/fb0/idle_notify"
@@ -65,8 +66,12 @@
return -1;
}
- enum {DEFAULT_IDLE_TIME = 70}; //ms
- if(not setIdleTimeout(DEFAULT_IDLE_TIME)) {
+ int defaultIdleTime = 70; //ms
+ char property[PROPERTY_VALUE_MAX] = {0};
+ if((property_get("debug.mdpcomp.idletime", property, NULL) > 0)) {
+ defaultIdleTime = atoi(property);
+ }
+ if(not setIdleTimeout(defaultIdleTime)) {
close(mTimeoutEventFd);
mTimeoutEventFd = -1;
return -1;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 6f2f0e3..ea40334 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -39,21 +39,22 @@
DECLARE_META_INTERFACE(QService);
enum {
COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
- SECURING, // Hardware securing start/end notification
- UNSECURING, // Hardware unsecuring start/end notification
- CONNECT, // Connect to qservice
- SCREEN_REFRESH, // Refresh screen through SF invalidate
- EXTERNAL_ORIENTATION, // Set external orientation
- BUFFER_MIRRORMODE, // Buffer mirrormode
- CHECK_EXTERNAL_STATUS, // Check status of external display
- GET_DISPLAY_ATTRIBUTES, // Get display attributes
- SET_HSIC_DATA, // Set HSIC on dspp
- GET_DISPLAY_VISIBLE_REGION, // Get the visibleRegion for dpy
- SET_SECONDARY_DISPLAY_STATUS, // Sets secondary display status
- SET_MAX_PIPES_PER_MIXER, // Set max pipes per mixer for MDPComp
- SET_VIEW_FRAME, // Set view frame of display
- DYNAMIC_DEBUG, // Enable more logging on the fly
- SET_IDLE_TIMEOUT, // Set idle timeout for GPU fallback
+ SECURING = 2, // Hardware securing start/end notification
+ UNSECURING = 3, // Hardware unsecuring start/end notification
+ CONNECT = 4, // Connect to qservice
+ SCREEN_REFRESH = 5, // Refresh screen through SF invalidate
+ EXTERNAL_ORIENTATION = 6,// Set external orientation
+ BUFFER_MIRRORMODE = 7, // Buffer mirrormode
+ CHECK_EXTERNAL_STATUS = 8,// Check status of external display
+ GET_DISPLAY_ATTRIBUTES = 9,// Get display attributes
+ SET_HSIC_DATA = 10, // Set HSIC on dspp
+ GET_DISPLAY_VISIBLE_REGION = 11,// Get the visibleRegion for dpy
+ SET_SECONDARY_DISPLAY_STATUS = 12,// Sets secondary display status
+ SET_MAX_PIPES_PER_MIXER = 13,// Set max pipes per mixer for MDPComp
+ SET_VIEW_FRAME = 14, // Set view frame of display
+ DYNAMIC_DEBUG = 15, // Enable more logging on the fly
+ SET_IDLE_TIMEOUT = 16, // Set idle timeout for GPU fallback
+ TOGGLE_BWC = 17, // Toggle BWC On/Off on targets that support
COMMAND_LIST_END = 400,
};