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,
     };