summaryrefslogtreecommitdiff
authorSky Zhou <sky.zhou@amlogic.com>2017-01-19 05:40:34 (GMT)
committer Gerrit Code Review <gituser@scgit.amlogic.com>2017-01-19 05:40:34 (GMT)
commit86947537de1d143e1759c31c1a5fb25b782e3e4a (patch)
tree6e076211da6bba113e502f429c5732c87ab9f41f
parente621a17c2cb80c9b1a48c98ec9dc6a59b14fb9fe (diff)
parent59f63517c6436cff1eecdc523d928165a8522da0 (diff)
downloadhwcomposer-86947537de1d143e1759c31c1a5fb25b782e3e4a.zip
hwcomposer-86947537de1d143e1759c31c1a5fb25b782e3e4a.tar.gz
hwcomposer-86947537de1d143e1759c31c1a5fb25b782e3e4a.tar.bz2
Merge "PD#138457: add hwc direct & ge2d compose mode." into n-amlogic
Diffstat
-rw-r--r--hwc2/common/base/HwcFenceControl.cpp214
-rw-r--r--hwc2/common/base/HwcLayer.cpp107
-rw-r--r--hwc2/common/base/HwcLayer.h37
-rw-r--r--hwc2/common/base/HwcModule.cpp15
-rw-r--r--hwc2/common/base/Hwcomposer.cpp27
-rw-r--r--hwc2/common/base/SimpleThread.h15
-rw-r--r--hwc2/common/base/VsyncManager.cpp14
-rw-r--r--hwc2/common/base/VsyncManager.h14
-rw-r--r--hwc2/common/composers/Composers.cpp42
-rw-r--r--hwc2/common/composers/Composers.h45
-rw-r--r--hwc2/common/composers/GE2DComposer.cpp702
-rw-r--r--hwc2/common/composers/GE2DComposer.cpp_632
-rw-r--r--hwc2/common/composers/GE2DComposer.h169
-rw-r--r--hwc2/common/composers/GE2DComposer.h_80
-rw-r--r--hwc2/common/devices/ExternalDevice.cpp14
-rw-r--r--hwc2/common/devices/PhysicalDevice.cpp763
-rw-r--r--hwc2/common/devices/PrimaryDevice.cpp18
-rw-r--r--hwc2/common/devices/VirtualDevice.cpp21
-rw-r--r--hwc2/common/observers/SoftVsyncObserver.cpp14
-rw-r--r--hwc2/common/observers/SoftVsyncObserver.h14
-rw-r--r--hwc2/common/observers/UeventObserver.cpp14
-rw-r--r--hwc2/common/utils/Dump.cpp14
-rw-r--r--hwc2/common/utils/Dump.h15
-rw-r--r--hwc2/common/utils/HwcTrace.h19
-rw-r--r--hwc2/common/utils/Utils.cpp40
-rw-r--r--hwc2/common/utils/Utils.h38
-rw-r--r--hwc2/include/ExternalDevice.h15
-rw-r--r--hwc2/include/HwcFenceControl.h133
-rw-r--r--hwc2/include/Hwcomposer.h15
-rw-r--r--hwc2/include/IComposer.h33
-rw-r--r--hwc2/include/IComposerFactory.h25
-rw-r--r--hwc2/include/IDisplayDevice.h36
-rw-r--r--hwc2/include/IPlatFactory.h15
-rw-r--r--hwc2/include/PhysicalDevice.h100
-rw-r--r--hwc2/include/PrimaryDevice.h21
-rw-r--r--hwc2/include/UeventObserver.h14
-rw-r--r--hwc2/include/VirtualDevice.h15
-rw-r--r--hwc2/platforms/Android.mk20
-rw-r--r--hwc2/platforms/PlatFactory.cpp19
-rw-r--r--hwc2/platforms/PlatFactory.h14
-rw-r--r--hwc2/test/nv12_ved_test.cpp15
41 files changed, 3339 insertions, 248 deletions
diff --git a/hwc2/common/base/HwcFenceControl.cpp b/hwc2/common/base/HwcFenceControl.cpp
new file mode 100644
index 0000000..69cd658
--- a/dev/null
+++ b/hwc2/common/base/HwcFenceControl.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+
+// We would eliminate the non-conforming zero-length array, but we can't since
+// this is effectively included from the Linux kernel
+#include <sync/sync.h>
+#include <sw_sync.h>
+
+#include <HwcFenceControl.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <HwcTrace.h>
+
+namespace android {
+namespace amlogic {
+
+const sp<HwcFenceControl> HwcFenceControl::NO_FENCE = sp<HwcFenceControl>(new HwcFenceControl);
+
+HwcFenceControl::HwcFenceControl() :
+ mFenceFd(-1) {
+}
+
+HwcFenceControl::HwcFenceControl(int32_t fenceFd) :
+ mFenceFd(fenceFd) {
+}
+
+HwcFenceControl::~HwcFenceControl() {
+ if (mFenceFd != -1) {
+ close(mFenceFd);
+ }
+}
+
+int32_t HwcFenceControl::createFenceTimeline() {
+ int32_t syncTimelineFd;
+
+ syncTimelineFd = sw_sync_timeline_create();
+ if (syncTimelineFd < 0) {
+ ETRACE("Stark, can't create sw_sync_timeline:");
+ return -1;
+ }
+
+ return syncTimelineFd;
+}
+
+int32_t HwcFenceControl::createFence(int32_t syncTimelineFd,
+ char* str, uint32_t val) {
+
+ int32_t fenceFd = sw_sync_fence_create(syncTimelineFd, str, val);
+ if (fenceFd < 0) {
+ ETRACE("can't create sync pt %d: %s", val, strerror(errno));
+ return -1;
+ }
+
+ return fenceFd;
+}
+
+status_t HwcFenceControl::syncTimelineInc(int32_t syncTimelineFd) {
+ status_t err;
+
+ err = sw_sync_timeline_inc(syncTimelineFd, 1);
+ if (err < 0) {
+ ETRACE("can't increment sync obj:");
+ return -1;
+ }
+ return err;
+}
+
+status_t HwcFenceControl::traceFenceInfo(int32_t fence) {
+ status_t err;
+ struct sync_fence_info_data *info;
+
+ err = sync_wait(fence, 10000);
+
+ if (err < 0) {
+ ALOGI("wait %d failed: %s\n", fence, strerror(errno));
+ } else {
+ ALOGI("wait %d done\n", fence);
+ }
+ info = sync_fence_info(fence);
+ if (info) {
+ struct sync_pt_info *pt_info = NULL;
+ ALOGI(" fence %s %d\n", info->name, info->status);
+
+ while ((pt_info = sync_pt_info(info, pt_info))) {
+ int ts_sec = pt_info->timestamp_ns / 1000000000LL;
+ int ts_usec = (pt_info->timestamp_ns % 1000000000LL) / 1000LL;
+ ALOGI(" pt %s %s %d %d.%06d", pt_info->obj_name,
+ pt_info->driver_name, pt_info->status,
+ ts_sec, ts_usec);
+ if (!strcmp(pt_info->driver_name, "sw_sync"))
+ ALOGI(" val=%d\n", *(uint32_t *)pt_info->driver_data);
+ else
+ ALOGI("\n");
+ }
+ sync_fence_info_free(info);
+ }
+
+ // closeFd( fence);
+ return err;
+}
+
+status_t HwcFenceControl::wait(int32_t fence, int32_t timeout) {
+ if (fence == -1) {
+ return NO_ERROR;
+ }
+ int32_t err = sync_wait(fence, timeout);
+ return err < 0 ? -errno : status_t(NO_ERROR);
+}
+
+status_t HwcFenceControl::waitForever(const char* logname) {
+ if (mFenceFd == -1) {
+ return NO_ERROR;
+ }
+ int32_t warningTimeout = 3000;
+ int32_t err = sync_wait(mFenceFd, warningTimeout);
+ if (err < 0 && errno == ETIME) {
+ ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
+ warningTimeout);
+ err = sync_wait(mFenceFd, TIMEOUT_NEVER);
+ }
+ return err < 0 ? -errno : status_t(NO_ERROR);
+}
+
+int32_t HwcFenceControl::merge(const String8& name, const int32_t& f1,
+ const int32_t& f2) {
+ int32_t result;
+ // Merge the two fences. In the case where one of the fences is not a
+ // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
+ // that a new fence with the given name is created.
+ if (f1 != -1 && f2 != -1) {
+ result = sync_merge(name.string(), f1, f2);
+ } else if (f1 != -1) {
+ result = sync_merge(name.string(), f1, f1);
+ } else if (f2 != -1) {
+ result = sync_merge(name.string(), f2, f2);
+ } else {
+ return -1;
+ }
+ if (result == -1) {
+ status_t err = -errno;
+ ETRACE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
+ name.string(), f1, f2,
+ strerror(-err), err);
+ return -1;
+ }
+ return result;
+}
+
+int32_t HwcFenceControl::dup() const {
+ return ::dup(mFenceFd);
+}
+
+int32_t HwcFenceControl::dupFence(int32_t fence) {
+ if (-1 == fence) {
+ DTRACE("acquire fence already been signaled.");
+ return -1;
+ }
+
+ int32_t dupFence = ::dup(fence);
+ if (dupFence < 0) {
+ ETRACE("acquire fence dup failed! please check it immeditely!");
+ }
+
+ return dupFence;
+}
+
+int32_t HwcFenceControl::getFenceFd() const {
+ return mFenceFd;
+}
+
+nsecs_t HwcFenceControl::getSignalTime() const {
+ if (mFenceFd == -1) {
+ return -1;
+ }
+
+ struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
+ if (finfo == NULL) {
+ ETRACE("sync_fence_info returned NULL for fd %d", mFenceFd);
+ return -1;
+ }
+ if (finfo->status != 1) {
+ sync_fence_info_free(finfo);
+ return INT64_MAX;
+ }
+
+ struct sync_pt_info* pinfo = NULL;
+ uint64_t timestamp = 0;
+ while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
+ if (pinfo->timestamp_ns > timestamp) {
+ timestamp = pinfo->timestamp_ns;
+ }
+ }
+ sync_fence_info_free(finfo);
+
+ return nsecs_t(timestamp);
+}
+
+} // namespace amlogic
+} // namespace android
diff --git a/hwc2/common/base/HwcLayer.cpp b/hwc2/common/base/HwcLayer.cpp
index 78bca07..98dc63f 100644
--- a/hwc2/common/base/HwcLayer.cpp
+++ b/hwc2/common/base/HwcLayer.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <inttypes.h>
@@ -10,7 +22,6 @@
#include <cutils/properties.h>
#include <sync/sync.h>
-#include <Utils.h>
namespace android {
namespace amlogic {
@@ -24,9 +35,27 @@ HwcLayer::HwcLayer(hwc2_display_t& dpy)
mPlaneAlpha(0.0f),
mTransform(HAL_TRANSFORM_RESERVED),
mZ(0),
+ mBufferHnd(NULL),
mInitialized(false)
{
-
+ // initial layer's state.
+ mColor.r = 0;
+ mColor.g = 0;
+ mColor.b = 0;
+ mColor.a = 0;
+
+ mSourceCrop.left = 0.0f;
+ mSourceCrop.top = 0.0f;
+ mSourceCrop.right = 0.0f;
+ mSourceCrop.bottom = 0.0f;
+
+ mDisplayFrame.left = 0;
+ mDisplayFrame.top = 0;
+ mDisplayFrame.right = 0;
+ mDisplayFrame.bottom = 0;
+
+ mDamageRegion.numRects = 0;
+ mVisibleRegion.numRects = 0;
}
HwcLayer::~HwcLayer()
@@ -50,9 +79,73 @@ void HwcLayer::deinitialize() {
void HwcLayer::resetAcquireFence() {
Mutex::Autolock _l(mLock);
+ HwcFenceControl::closeFd(mAcquireFence);
mAcquireFence = -1;
}
+bool HwcLayer::isCropped() {
+ bool rtn = true;
+ private_handle_t const* buffer = reinterpret_cast<private_handle_t const*>(mBufferHnd);
+
+ if (buffer && buffer->width && buffer->height) {
+ float widthCmp = (mSourceCrop.right - mSourceCrop.left) / buffer->width;
+ float heightCmp = (mSourceCrop.bottom - mSourceCrop.top) / buffer->height;
+
+ if (widthCmp == 1.0f && heightCmp == 1.0f)
+ rtn = false;
+ }
+
+ DTRACE("chkIsCropped %d", rtn);
+ return rtn;
+}
+
+bool HwcLayer::isScaled() {
+ bool rtn = true;
+ float sourceWidth = mSourceCrop.right - mSourceCrop.left;
+ float sourceHeight = mSourceCrop.bottom - mSourceCrop.top;
+ int displayWidth = mDisplayFrame.right - mDisplayFrame.left;
+ int displayHeight = mDisplayFrame.bottom - mDisplayFrame.top;
+
+ if (displayWidth > 0 && displayHeight > 0) {
+ float widthCmp = sourceWidth / displayWidth;
+ float heightCmp = sourceHeight / displayHeight;
+
+ if (widthCmp == 1.0f && heightCmp == 1.0f)
+ rtn = false;
+ }
+
+ DTRACE("chkIsScaled %d", rtn);
+ return rtn;
+}
+
+bool HwcLayer::isOffset() {
+ bool rtn = false;
+ if (mDisplayFrame.left != 0 || mDisplayFrame.top != 0)
+ rtn = true;
+
+ DTRACE("chkIsOffset %d", rtn);
+ return rtn;
+}
+
+bool HwcLayer::isBlended() {
+ DTRACE("chkIsBlended %d", mBlendMode);
+ return mBlendMode != HWC2_BLEND_MODE_INVALID;
+}
+
+bool HwcLayer::haveColor() {
+ DTRACE("[%d, %d, %d, %d]", mColor.r, mColor.g, mColor.b, mColor.a);
+ return !(0 == mColor.r && 0 == mColor.g && 0 == mColor.b && 0 == mColor.a);
+}
+
+bool HwcLayer::havePlaneAlpha() {
+ DTRACE("mPlaneAlpha: %d", mPlaneAlpha);
+ return mPlaneAlpha > 0.0f && mPlaneAlpha < 1.0f;
+}
+
+bool HwcLayer::haveDataspace() {
+ DTRACE("mDataSpace: %d", mDataSpace);
+ return mDataSpace != HAL_DATASPACE_UNKNOWN;
+}
int32_t HwcLayer::setBuffer(buffer_handle_t buffer, int32_t acquireFence) {
Mutex::Autolock _l(mLock);
@@ -62,16 +155,10 @@ int32_t HwcLayer::setBuffer(buffer_handle_t buffer, int32_t acquireFence) {
return HWC2_ERROR_BAD_PARAMETER;
if (NULL == buffer) {
- //mBufferHnd = buffer;
- // if (-1 != acquireFence) mAcquireFence = acquireFence;
- //} else {
DTRACE("Layer buffer is null! no need to update this layer.");
}
mBufferHnd = buffer;
mAcquireFence = acquireFence;
- if (mAcquireFence > -1) {
- sync_wait(mAcquireFence, 4000);
- }
return HWC2_ERROR_NONE;
}
@@ -256,7 +343,7 @@ void HwcLayer::dump(Dump& d) {
"SIDEBAND"};
d.append(
- " %11s | %08" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
+ " %11s | %12" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
compositionTypeName[mCompositionType], intptr_t(mBufferHnd),
mZ, mDataSpace, mPlaneAlpha, mTransform, mBlendMode,
mSourceCrop.left, mSourceCrop.top, mSourceCrop.right, mSourceCrop.bottom,
diff --git a/hwc2/common/base/HwcLayer.h b/hwc2/common/base/HwcLayer.h
index 50c6d35..7af99b2 100644
--- a/hwc2/common/base/HwcLayer.h
+++ b/hwc2/common/base/HwcLayer.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef HWC_LAYER_H
#define HWC_LAYER_H
@@ -8,7 +21,8 @@
#include <utils/threads.h>
#include <Dump.h>
#include <utils/Vector.h>
-
+#include <Utils.h>
+#include <HwcFenceControl.h>
namespace android {
namespace amlogic {
@@ -38,9 +52,20 @@ class HwcLayer {
int32_t setCompositionType(int32_t type);
int32_t getCompositionType() const { return mCompositionType; }
+ // get HWC2 Layer state functions
buffer_handle_t getBufferHandle() const { return mBufferHnd; }
const native_handle_t* getSidebandStream() const { return mSidebandStream; }
int32_t getAcquireFence() const { return mAcquireFence; }
+ int32_t getDuppedAcquireFence() { return HwcFenceControl::dupFence(mAcquireFence); }
+ hwc_region_t getSurfaceDamage() { return mDamageRegion; };
+ int32_t getBlendMode() { return mBlendMode; };
+ hwc_color_t getColor() { return mColor; };
+ int32_t getDataspace() { return mDataSpace; };
+ hwc_rect_t getDisplayFrame() { return mDisplayFrame;};
+ float getPlaneAlpha() { return mPlaneAlpha; };
+ hwc_frect_t getSourceCrop() { return mSourceCrop; };
+ int32_t getTransform() { return mTransform; };
+ hwc_region_t getVisibleRegion() { return mVisibleRegion; };
bool initialize();
void deinitialize();
@@ -48,6 +73,14 @@ class HwcLayer {
void resetAcquireFence();
+ bool isCropped();
+ bool isScaled();
+ bool isOffset();
+ bool isBlended();
+ bool haveColor();
+ bool havePlaneAlpha();
+ bool haveDataspace();
+
#if WITH_LIBPLAYER_MODULE
void presentOverlay();
#endif
diff --git a/hwc2/common/base/HwcModule.cpp b/hwc2/common/base/HwcModule.cpp
index e48f6ee..4c7991a 100644
--- a/hwc2/common/base/HwcModule.cpp
+++ b/hwc2/common/base/HwcModule.cpp
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#include <hardware/hardware.h>
#include <string.h>
#include <stdio.h>
diff --git a/hwc2/common/base/Hwcomposer.cpp b/hwc2/common/base/Hwcomposer.cpp
index 65040d3..687c9f2 100644
--- a/hwc2/common/base/Hwcomposer.cpp
+++ b/hwc2/common/base/Hwcomposer.cpp
@@ -1,10 +1,24 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#include <HwcTrace.h>
#include <Hwcomposer.h>
#include <Dump.h>
#include <UeventObserver.h>
+#include <inttypes.h>
namespace android {
namespace amlogic {
@@ -405,7 +419,8 @@ int32_t Hwcomposer::setClientTarget(
int32_t acquireFence,
int32_t /*android_dataspace_t*/ dataspace,
hwc_region_t damage) {
- DTRACE("setClientTarget disp = %d", (int32_t)display);
+ DTRACE("setClientTarget disp = %d, targetHnd = %" PRIxPTR ","
+ "acquireFence = %d, dataspace = %d", (int32_t)display, target, acquireFence, dataspace);
IDisplayDevice *device = getDisplayDevice((int32_t)display);
if (!device) {
@@ -420,7 +435,7 @@ int32_t Hwcomposer::setClientTarget(
int32_t Hwcomposer::setColorMode(
hwc2_display_t display,
int32_t /*android_color_mode_t*/ mode) {
- DTRACE("setColorMode disp = %d", (int32_t)display);
+ DTRACE("setColorMode disp = %d, mode = %d", (int32_t)display, mode);
IDisplayDevice *device = getDisplayDevice((int32_t)display);
if (!device) {
@@ -435,7 +450,7 @@ int32_t Hwcomposer::setColorTransform(
hwc2_display_t display,
const float* matrix,
int32_t /*android_color_transform_t*/ hint) {
- DTRACE("setColorTransform disp = %d", (int32_t)display);
+ DTRACE("setColorTransform disp = %d, hint = %d", (int32_t)display, hint);
IDisplayDevice *device = getDisplayDevice((int32_t)display);
if (!device) {
@@ -450,7 +465,7 @@ int32_t Hwcomposer::setOutputBuffer(
hwc2_display_t display,
buffer_handle_t buffer,
int32_t releaseFence) {
- DTRACE("setOutputBuffer disp = %d", (int32_t)display);
+ DTRACE("setOutputBuffer disp = %d, releaseFence = %d", (int32_t)display, releaseFence);
if (display != HWC_DISPLAY_VIRTUAL) {
ETRACE("Should be a virtual display: %d", (int32_t)display);
return HWC2_ERROR_UNSUPPORTED;
@@ -468,7 +483,7 @@ int32_t Hwcomposer::setOutputBuffer(
int32_t Hwcomposer::setPowerMode(
hwc2_display_t display,
int32_t /*hwc2_power_mode_t*/ mode) {
- DTRACE("setPowerMode disp = %d", (int32_t)display);
+ DTRACE("setPowerMode disp = %d, mode = %d", (int32_t)display, mode);
IDisplayDevice *device = getDisplayDevice((int32_t)display);
if (!device) {
diff --git a/hwc2/common/base/SimpleThread.h b/hwc2/common/base/SimpleThread.h
index 8842c21..7cf51cf 100644
--- a/hwc2/common/base/SimpleThread.h
+++ b/hwc2/common/base/SimpleThread.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef SIMPLE_THREAD_H
#define SIMPLE_THREAD_H
diff --git a/hwc2/common/base/VsyncManager.cpp b/hwc2/common/base/VsyncManager.cpp
index 22e896b..13b705e 100644
--- a/hwc2/common/base/VsyncManager.cpp
+++ b/hwc2/common/base/VsyncManager.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <HwcTrace.h>
diff --git a/hwc2/common/base/VsyncManager.h b/hwc2/common/base/VsyncManager.h
index 6c5dfe1..3ad81c6 100644
--- a/hwc2/common/base/VsyncManager.h
+++ b/hwc2/common/base/VsyncManager.h
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#ifndef VSYNC_MANAGER_H
diff --git a/hwc2/common/composers/Composers.cpp b/hwc2/common/composers/Composers.cpp
new file mode 100644
index 0000000..093386c
--- a/dev/null
+++ b/hwc2/common/composers/Composers.cpp
@@ -0,0 +1,42 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+
+#include <HwcTrace.h>
+#include <Composers.h>
+#include <IDisplayDevice.h>
+
+
+namespace android {
+namespace amlogic {
+
+Composers::Composers(IDisplayDevice& disp)
+ : mDisplayDevice(disp),
+ mInitialized(false)
+{
+}
+
+Composers::~Composers()
+{
+ WARN_IF_NOT_DEINIT();
+}
+
+bool Composers::initialize(framebuffer_info_t* fbInfo)
+{
+ if (mInitialized) {
+ WTRACE("object has been initialized");
+ return true;
+ }
+
+ mInitialized = true;
+ return true;
+}
+
+void Composers::deinitialize()
+{
+ mInitialized = false;
+}
+
+} // namespace amlogic
+} // namesapce android
+
diff --git a/hwc2/common/composers/Composers.h b/hwc2/common/composers/Composers.h
new file mode 100644
index 0000000..ae48eee
--- a/dev/null
+++ b/hwc2/common/composers/Composers.h
@@ -0,0 +1,45 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+
+#ifndef COMPOSERS_H
+#define COMPOSERS_H
+
+#include <IComposer.h>
+
+namespace android {
+namespace amlogic {
+
+// class IComposer;
+class IDisplayDevice;
+
+class Composers :public IComposer {
+public:
+ Composers(IDisplayDevice& disp);
+ virtual ~Composers();
+
+public:
+
+ virtual bool initialize(framebuffer_info_t* fbInfo);
+ virtual void deinitialize();
+ virtual int32_t startCompose(Vector< hwc2_layer_t > hwcLayers, int32_t *offset = 0, int32_t frameCount = 0) = 0;
+ virtual const char* getName() const = 0;
+ // virtual void setCurGlesFbSlot(uint32_t slot) = 0;
+ virtual const buffer_handle_t getBufHnd() = 0;
+ virtual void mergeRetireFence(int32_t slot, int32_t retireFence) = 0;
+ virtual void removeRetireFence(int32_t slot) = 0;
+ virtual void setVideoOverlayLayerId(hwc2_layer_t layerId) = 0;
+ virtual void fillRectangle(hwc_rect_t clipRect, uint32_t color, uint32_t addr) = 0;
+
+private:
+ IDisplayDevice& mDisplayDevice;
+
+ bool mInitialized;
+};
+
+} // namespace amlogic
+} // namespace android
+
+
+#endif /* COMPOSERS_H */
+
diff --git a/hwc2/common/composers/GE2DComposer.cpp b/hwc2/common/composers/GE2DComposer.cpp
new file mode 100644
index 0000000..9611989
--- a/dev/null
+++ b/hwc2/common/composers/GE2DComposer.cpp
@@ -0,0 +1,702 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+#include <HwcTrace.h>
+#include <HwcFenceControl.h>
+#include <GE2DComposer.h>
+#include <inttypes.h>
+#include <linux/ion.h>
+#include <ion/ion.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+
+namespace android {
+namespace amlogic {
+
+GE2DComposer::GE2DComposer(IDisplayDevice& disp)
+ : Composers(disp),
+ mDisplayDevice(disp),
+ mLock(),
+ mSyncTimelineFd(-1),
+ mCondition(),
+ mQueueItems(),
+ mQueuedFrames(0),
+ mBufferMask(0),
+ mNumBuffers(1),
+ mFbSlot(0),
+ mCurGlesFbSlot(-1),
+ mSingleFbSize(0),
+ mGe2dBufHnd(NULL),
+ mBasePhyAddr(0),
+ mGe2dFd(-1),
+ mVideoLayerId(0),
+ mSrcBufferInfo(NULL),
+ mDebug(false),
+ mExitThread(false),
+ mInitialized(false)
+{
+ mName = "GE2D";
+
+ mQueueItems.setCapacity(8);
+ mQueueItems.clear();
+}
+
+GE2DComposer::~GE2DComposer()
+{
+ WARN_IF_NOT_DEINIT();
+}
+
+int32_t GE2DComposer::allocBuffer(private_module_t* module, size_t size, int32_t usage, buffer_handle_t* pHandle)
+{
+ ion_user_handle_t ion_hnd;
+ unsigned char *cpu_ptr = NULL;
+ int32_t shared_fd;
+ int32_t ret;
+ int32_t ion_flags = 0;
+ int32_t lock_state = 0;
+
+ if (usage & GRALLOC_USAGE_AML_DMA_BUFFER)
+ {
+ ret = ion_alloc(module->ion_client, size, 0, ION_HEAP_CARVEOUT_MASK,
+ ion_flags, &ion_hnd);
+ }
+
+ if ( ret != 0)
+ {
+ ETRACE("Failed to ion_alloc from ion_client:%d", module->ion_client);
+ return -1;
+ }
+
+ ret = ion_share( module->ion_client, ion_hnd, &shared_fd );
+ if ( ret != 0 )
+ {
+ ETRACE( "ion_share( %d ) failed", module->ion_client );
+ if ( 0 != ion_free( module->ion_client, ion_hnd ) )
+ ETRACE( "ion_free( %d ) failed", module->ion_client );
+ return -1;
+ }
+
+ if (!(usage & GRALLOC_USAGE_PROTECTED))
+ {
+ cpu_ptr = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0 );
+
+ if ( MAP_FAILED == cpu_ptr )
+ {
+ ETRACE( "ion_map( %d ) failed", module->ion_client );
+ if ( 0 != ion_free( module->ion_client, ion_hnd ) )
+ ETRACE( "ion_free( %d ) failed", module->ion_client );
+ close( shared_fd );
+ return -1;
+ }
+ lock_state = private_handle_t::LOCK_STATE_MAPPED;
+ }
+
+ private_handle_t *hnd = new private_handle_t( private_handle_t::PRIV_FLAGS_USES_ION /*TODO ion extend*| priv_heap_flag*/,
+ usage, size, cpu_ptr, lock_state );
+
+ if ( NULL != hnd )
+ {
+ hnd->share_fd = shared_fd;
+ hnd->ion_hnd = ion_hnd;
+ /*TODO ion extend hnd->min_pgsz = min_pgsz; */
+ *pHandle = hnd;
+ return 0;
+ }
+ else
+ {
+ ETRACE( "Gralloc out of mem for ion_client:%d", module->ion_client );
+ }
+
+ close( shared_fd );
+
+ if (!(usage & GRALLOC_USAGE_PROTECTED))
+ {
+ ret = munmap( cpu_ptr, size );
+ if ( 0 != ret )
+ ETRACE( "munmap failed for base:%p size: %zd", cpu_ptr, size );
+ }
+
+ ret = ion_free( module->ion_client, ion_hnd );
+ if ( 0 != ret )
+ ETRACE( "ion_free( %d ) failed", module->ion_client );
+ return -1;
+}
+
+void GE2DComposer::freeBuffer(private_handle_t const* hnd, private_module_t* m)
+{
+ if ( hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION )
+ {
+ /* Buffer might be unregistered already so we need to assure we have a valid handle*/
+ if ( 0 != hnd->base )
+ {
+ if ( 0 != munmap( (void*)hnd->base, hnd->size ) ) ETRACE( "Failed to munmap handle %p", hnd );
+ }
+ close( hnd->share_fd );
+ if ( 0 != ion_free( m->ion_client, hnd->ion_hnd ) ) ETRACE( "Failed to ion_free( ion_client: %d ion_hnd: %p )", m->ion_client, hnd->ion_hnd );
+ memset( (void*)hnd, 0, sizeof( *hnd ) );
+ }
+}
+
+bool GE2DComposer::initialize(framebuffer_info_t* fbInfo)
+{
+ Mutex::Autolock _l(mLock);
+
+ if (mInitialized) {
+ WTRACE("object has been initialized");
+ return true;
+ }
+
+ // create a release fence timeline.
+ mSyncTimelineFd = HwcFenceControl::createFenceTimeline();
+ if (mSyncTimelineFd == -1) {
+ DEINIT_AND_RETURN_FALSE("sync timeline create failed!");
+ }
+ mCurrentSyncTime = 1;
+
+ // create ge2d composer thread.
+ mExitThread = false;
+ mThread = new GE2DRenderThread(this);
+ if (!mThread.get()) {
+ DEINIT_AND_RETURN_FALSE("failed to create ge2d composer thread.");
+ }
+ mThread->run("GE2DComposer", PRIORITY_URGENT_DISPLAY);
+
+ // framebuffer stuff.
+ mFbInfo = fbInfo;
+ mSingleFbSize = fbInfo->finfo.line_length * fbInfo->info.yres;
+ mNumBuffers = fbInfo->fbSize / mSingleFbSize;
+
+ if (!mGe2dBufHnd) {
+ int32_t usage = GRALLOC_USAGE_AML_DMA_BUFFER;
+ int32_t ret = allocBuffer(mFbInfo->grallocModule, mFbInfo->fbSize, usage, &mGe2dBufHnd);
+ if (ret < 0) {
+ ETRACE("allocBuffer failed!");
+ return false;
+ }
+ mBasePhyAddr = getIonPhyAddr(mFbInfo, mGe2dBufHnd);
+ } else {
+ DTRACE("Buffer alloced already.");
+ }
+
+ // ge2d info.
+ mSrcBufferInfo = new aml_ge2d_info_t();
+
+ // ge2d init.
+ mGe2dFd = ge2d_open();
+ mInitialized = true;
+ return true;
+}
+
+void GE2DComposer::deinitialize()
+{
+ mExitThread = true;
+ mCondition.signal();
+
+ if (mThread.get()) {
+ mThread->requestExitAndWait();
+ mThread = NULL;
+ }
+
+ if (mSrcBufferInfo) {
+ delete mSrcBufferInfo;
+ mSrcBufferInfo = NULL;
+ }
+
+ private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(mGe2dBufHnd);
+ if (NULL != hnd) {
+ freeBuffer(hnd, mFbInfo->grallocModule);
+ mGe2dBufHnd = NULL;
+ }
+
+ // ge2d exit.
+ ge2d_close(mGe2dFd);
+ mInitialized = false;
+}
+
+const char* GE2DComposer::getName() const
+{
+ return mName;
+}
+
+const buffer_handle_t GE2DComposer::getBufHnd()
+{
+ Mutex::Autolock _l(mLock);
+
+ return mGe2dBufHnd;
+}
+
+/* void GE2DComposer::setCurGlesFbSlot(uint32_t slot)
+{
+ Mutex::Autolock _l(mLock);
+
+ mCurGlesFbSlot = slot;
+}*/
+
+void GE2DComposer::mergeRetireFence(int32_t slot, int32_t retireFence)
+{
+ Mutex::Autolock _l(mLock);
+ DTRACE("slot:%d, retireFence: %d", slot, retireFence);
+
+ int32_t index = slot / mFbInfo->info.yres;
+ mSlots[index].mSlot = slot;
+ int32_t tempFence = HwcFenceControl::merge(String8("retire_fences"), mSlots[index].mFence, retireFence);
+ HwcFenceControl::closeFd(retireFence);
+ HwcFenceControl::closeFd(mSlots[index].mFence);
+ mSlots[index].mFence = tempFence;
+}
+
+void GE2DComposer::removeRetireFence(int32_t slot)
+{
+ Mutex::Autolock _l(mLock);
+ DTRACE("slot:%d", slot);
+
+ int32_t index = slot / mFbInfo->info.yres;
+ // mSlots[index].mSlot = 0;
+ HwcFenceControl::closeFd(mSlots[index].mFence);
+ mSlots[index].mFence = -1;
+}
+
+void GE2DComposer::setVideoOverlayLayerId(hwc2_layer_t layerId)
+{
+ Mutex::Autolock _l(mLock);
+ DTRACE("layerId:%d", layerId);
+
+ mVideoLayerId = layerId;
+}
+
+uint32_t GE2DComposer::findFreeFbSlot()
+{
+ int32_t fbSlot = 0;
+
+ if (mNumBuffers == 1) {
+ // If we have only one buffer, we never use page-flipping.
+ return 0;
+ }
+
+ if (mBufferMask >= ((1LU<<mNumBuffers)-1)) {
+ // We ran out of buffers. reinit to 0;
+ mBufferMask = 0x1;
+ return 0;
+ }
+
+ // find a free slot
+ for (uint32_t i=0 ; i<mNumBuffers ; i++) {
+ if ((mBufferMask & (1LU<<i)) == 0) {
+ mBufferMask |= (1LU<<i);
+ break;
+ }
+
+ fbSlot += mFbInfo->info.yres;
+ }
+
+ return fbSlot;
+}
+
+int32_t GE2DComposer::startCompose(
+ Vector< hwc2_layer_t > hwcLayers,
+ int32_t *offset, int32_t frameCount)
+{
+ Mutex::Autolock _l(mLock);
+
+ // find a free slot of fb.
+ *offset = mFbSlot = findFreeFbSlot();
+
+ { // clear display region.
+ hwc_rect_t clipRect;
+
+ HwcLayer* videoLayer = mDisplayDevice.getLayerById(mVideoLayerId);
+ uint32_t addr = mBasePhyAddr + mFbSlot * mFbInfo->finfo.line_length;
+ if (videoLayer) {
+ clipRect = videoLayer->getDisplayFrame();
+ fillRectangle(clipRect, 0, addr);
+ mVideoLayerId = 0;
+ }
+
+ if (frameCount < 3) {
+ clipRect.left = 0;
+ clipRect.top = 0;
+ clipRect.right = mFbInfo->info.xres;
+ clipRect.bottom = mFbInfo->info.yres;
+ fillRectangle(clipRect, 0, addr);
+ }
+ }
+
+ // add hwcLayers to work queue.
+ int32_t index = mFbSlot / mFbInfo->info.yres;
+ mSlots[index].mSlot = mFbSlot;
+ mSlots[index].mLayersState.clear();
+ for (uint32_t i=0; i<hwcLayers.size(); i++) {
+ hwc2_layer_t layerId = hwcLayers.itemAt(i);
+ HwcLayer* hwcLayer = mDisplayDevice.getLayerById(layerId);
+ if (NULL != hwcLayer) {
+ // Merge layers's fences and prior retire fence.
+ int32_t fence = hwcLayer->getDuppedAcquireFence();
+ int32_t tempFence = HwcFenceControl::merge(String8("layers"), fence, mSlots[index].mFence);
+ HwcFenceControl::closeFd(mSlots[index].mFence);
+ HwcFenceControl::closeFd(fence);
+ mSlots[index].mFence = tempFence;
+
+ // push layers state to mQueueItems.
+ LayerState* layerState = new LayerState();
+ layerState->setLayerState(hwcLayer);
+ mSlots[index].mLayersState.push_back(layerState);
+ }
+ }
+ // mSlots[index].mLayersState = layersState;
+ android_atomic_inc(&mQueuedFrames);
+ mQueueItems.push_back(mSlots[index]);
+ mSlots[index].mFence = -1;
+
+ int32_t ge2dFence = HwcFenceControl::createFence(mSyncTimelineFd, "ge2d_flag_fence", mCurrentSyncTime++);
+
+ mCondition.signal();
+ return ge2dFence;
+}
+
+void GE2DComposer::fillRectangle(hwc_rect_t clipRect, uint32_t color, uint32_t addr)
+{
+ mSrcBufferInfo->src_info[0].paddr = addr;
+ mSrcBufferInfo->src_info[0].format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mSrcBufferInfo->src_info[0].rect.x = clipRect.left;
+ mSrcBufferInfo->src_info[0].rect.y = clipRect.top;
+ mSrcBufferInfo->src_info[0].rect.w = clipRect.right - clipRect.left;
+ mSrcBufferInfo->src_info[0].rect.h = clipRect.bottom - clipRect.top;
+ mSrcBufferInfo->src_info[0].canvas_w = clipRect.right - clipRect.left;
+ mSrcBufferInfo->src_info[0].canvas_h = clipRect.bottom - clipRect.top;
+ mSrcBufferInfo->src_info[0].memtype = CANVAS_ALLOC;
+
+ mSrcBufferInfo->dst_info.paddr = addr;
+ mSrcBufferInfo->dst_info.format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mSrcBufferInfo->color = color;
+ mSrcBufferInfo->offset = 0;
+ mSrcBufferInfo->dst_info.rect.x = clipRect.left;
+ mSrcBufferInfo->dst_info.rect.y = clipRect.top;
+ mSrcBufferInfo->dst_info.rect.w = clipRect.right - clipRect.left;
+ mSrcBufferInfo->dst_info.rect.h = clipRect.bottom - clipRect.top;
+ mSrcBufferInfo->dst_info.canvas_w = clipRect.right - clipRect.left;
+ mSrcBufferInfo->dst_info.canvas_h = clipRect.bottom - clipRect.top;
+ mSrcBufferInfo->dst_info.memtype = CANVAS_ALLOC;
+ mSrcBufferInfo->ge2d_op = AML_GE2D_FILLRECTANGLE;
+ ge2d_process(mGe2dFd, mSrcBufferInfo);
+}
+
+bool GE2DComposer::isFullScreen(
+ hwc_rect_t displayFrame)
+{
+ if (displayFrame.left == 0
+ && displayFrame.top == 0
+ && displayFrame.right == mFbInfo->info.xres
+ && displayFrame.bottom == mFbInfo->info.yres) {
+ return true;
+ }
+
+ return false;
+}
+
+void GE2DComposer::tracer()
+{
+ static char const* ge2dOp[] = {
+ "AML_GE2D_FILLRECTANGLE",
+ "AML_GE2D_BLEND",
+ "AML_GE2D_STRETCHBLIT",
+ "AML_GE2D_BLIT",
+ "AML_GE2D_NONE"};
+
+ static char const* memType[] = {
+ "CANVAS_OSD0",
+ "CANVAS_OSD1",
+ "CANVAS_ALLOC",
+ "CANVAS_INVALID"};
+ ALOGE(" OP: %22s", ge2dOp[mSrcBufferInfo->ge2d_op]);
+ ALOGE(
+ " addr | memtype | canvas size | fmt | tr | blnd |"
+ " source crop (x,y,w,h) |\n"
+ " --------------+-----------------+-------------+-----+----+------|"
+ "--------------------------------+\n");
+ ALOGE(
+ " SRC0:\n"
+ " %12x | %15s | %5dx%5d | %03x | %02s | %04s |%5d,%5d,%5d,%5d \n",
+ mSrcBufferInfo->src_info[0].paddr, memType[mSrcBufferInfo->src_info[0].memtype],
+ mSrcBufferInfo->src_info[0].canvas_w, mSrcBufferInfo->src_info[0].canvas_h, mSrcBufferInfo->src_info[0].format,
+ "no", " no", mSrcBufferInfo->src_info[0].rect.x, mSrcBufferInfo->src_info[0].rect.y,
+ mSrcBufferInfo->src_info[0].rect.w, mSrcBufferInfo->src_info[0].rect.h);
+ ALOGE(
+ " SRC1:\n"
+ " %12x | %15s | %5dx%5d | %03x | %02s | %04s |%5d,%5d,%5d,%5d \n",
+ mSrcBufferInfo->src_info[1].paddr, memType[mSrcBufferInfo->src_info[1].memtype],
+ mSrcBufferInfo->src_info[1].canvas_w, mSrcBufferInfo->src_info[1].canvas_h, mSrcBufferInfo->src_info[1].format,
+ "no", " no", mSrcBufferInfo->src_info[1].rect.x, mSrcBufferInfo->src_info[1].rect.y,
+ mSrcBufferInfo->src_info[1].rect.w, mSrcBufferInfo->src_info[1].rect.h);
+ ALOGE(
+ " DST:\n"
+ " %12x | %15s | %5dx%5d | %03x | %02x | %04x |%5d,%5d,%5d,%5d \n",
+ mSrcBufferInfo->dst_info.paddr, memType[mSrcBufferInfo->dst_info.memtype],
+ mSrcBufferInfo->dst_info.canvas_w, mSrcBufferInfo->dst_info.canvas_h, mSrcBufferInfo->dst_info.format,
+ mSrcBufferInfo->dst_info.rotation, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y,
+ mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+ ALOGE(
+ " --------------+-----------------+-------------+-----+----+------|"
+ "--------------------------------+\n\n");
+}
+
+void GE2DComposer::dumpLayers(
+ private_handle_t const* hnd)
+{
+ void *layerBuffer = NULL;
+
+ layerBuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
+ if (layerBuffer != MAP_FAILED) {
+#if 1
+ int32_t base = 4 * (hnd->stride * (hnd->height / 2) + 10);
+ char* tmp = (char*)layerBuffer + base;
+ ALOGD("[0x%x, 0x%x, 0x%x, 0x%x]\n"
+ "[0x%x, 0x%x, 0x%x, 0x%x]\n"
+ "[0x%x, 0x%x, 0x%x, 0x%x]\n"
+ "[0x%x, 0x%x, 0x%x, 0x%x]\n",
+ tmp[0], tmp[1], tmp[2], tmp[3],
+ tmp[4], tmp[5], tmp[6], tmp[7],
+ tmp[8], tmp[9], tmp[10], tmp[11],
+ tmp[12], tmp[13], tmp[14], tmp[15]);
+#else
+ int fd;
+ char path[128];
+
+ sprintf(path, "/data/local/tmp/layer_%" PRId64 ".bin", systemTime(SYSTEM_TIME_MONOTONIC));
+ fd = open(path, O_RDWR | O_CREAT);
+ if (-1 == fd) {
+ ALOGE("Stark, open file failed!");
+ return;
+ }
+ write(fd, layerBuffer, hnd->size);
+ sync();
+ close(fd);
+#endif
+ munmap(layerBuffer, hnd->size);
+ ALOGD("dumpLayer ok");
+ } else {
+ ALOGE("layerBuffer mmap fail");
+ }
+}
+
+void GE2DComposer::runGE2DProcess(int32_t slot, Vector< LayerState* > &hwcLayersState)
+{
+ bool sameSize = false;
+ hwc_frect_t sourceCrop[GE2D_COMPOSE_MAX_LAYERS];
+ const LayerState* layer[GE2D_COMPOSE_MAX_LAYERS] = { NULL, NULL, NULL };
+ private_handle_t const* hnd[GE2D_COMPOSE_MAX_LAYERS] = { NULL, NULL, NULL };
+ uint32_t layerNum = hwcLayersState.size();
+ hwc_rect_t displayFrame[GE2D_COMPOSE_MAX_LAYERS];
+
+ for (int32_t i=0; i<layerNum; i++) {
+ layer[i] = hwcLayersState.itemAt(i);
+ sourceCrop[i] = layer[i]->mSourceCrop;
+ displayFrame[i] = layer[i]->mDisplayFrame;
+ hnd[i] = reinterpret_cast<private_handle_t const*>(layer[i]->mBufferHnd);
+ ALOGD("layer[%d] zorder: %d, blend: %d, PlaneAlpha: %f, "
+ "mColor: [%d, %d, %d, %d], mDataSpace: %d, format hnd[%d]: %x",
+ i, layer[i]->mZ, layer[i]->mBlendMode, layer[i]->mPlaneAlpha,
+ layer[i]->mColor.r, layer[i]->mColor.g, layer[i]->mColor.b,
+ layer[i]->mColor.a, layer[i]->mDataSpace, i, hnd[i]->format);
+ }
+
+#if 1 // TODO:2 same size layers case.
+ if (layerNum > GE2D_COMPOSE_ONE_LAYER) {
+ if (Utils::compareRect(sourceCrop[0], sourceCrop[1])
+ && Utils::compareRect(sourceCrop[0], displayFrame[0])
+ && Utils::compareRect(sourceCrop[1], displayFrame[1])) {
+ sameSize = true;
+ // swap layers and hnds.
+ Utils::swap(layer[0], layer[1]);
+ Utils::swap(hnd[0], hnd[1]);
+ }
+ }
+#endif
+
+ if ((layerNum == GE2D_COMPOSE_TWO_LAYERS && !hnd[1])
+ || (layerNum == GE2D_COMPOSE_MAX_LAYERS && (!hnd[1] || !hnd[2]))) {
+ ETRACE("%d layers compose, hnd should not be null", layerNum);
+ return;
+ }
+
+ mSrcBufferInfo->offset = 0;
+ if (sameSize) {
+ for (int32_t i=0; i<GE2D_COMPOSE_TWO_LAYERS; i++) {
+ mSrcBufferInfo->src_info[i].paddr = getIonPhyAddr(mFbInfo, hnd[i]);
+ mSrcBufferInfo->src_info[i].format = hnd[i]->format;
+ mSrcBufferInfo->src_info[i].rect.x = (int32_t)sourceCrop[i].left;
+ mSrcBufferInfo->src_info[i].rect.y = (int32_t)sourceCrop[i].top;
+ mSrcBufferInfo->src_info[i].rect.w = (int32_t)(sourceCrop[i].right - sourceCrop[i].left);
+ mSrcBufferInfo->src_info[i].rect.h = (int32_t)(sourceCrop[i].bottom- sourceCrop[i].top);
+ mSrcBufferInfo->src_info[i].canvas_w = hnd[i]->stride;
+ mSrcBufferInfo->src_info[i].canvas_h = hnd[i]->height;
+ mSrcBufferInfo->src_info[i].memtype = CANVAS_ALLOC;
+ }
+
+ mSrcBufferInfo->blend_mode = layer[0]->mBlendMode;
+
+ mSrcBufferInfo->dst_info.paddr = mBasePhyAddr + slot * mFbInfo->finfo.line_length;
+ mSrcBufferInfo->dst_info.format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mSrcBufferInfo->dst_info.rect.x = displayFrame[0].left;
+ mSrcBufferInfo->dst_info.rect.y = displayFrame[0].top;
+ mSrcBufferInfo->dst_info.rect.w = displayFrame[0].right - displayFrame[0].left;
+ mSrcBufferInfo->dst_info.rect.h = displayFrame[0].bottom - displayFrame[0].top;
+ mSrcBufferInfo->dst_info.canvas_w = mFbInfo->info.xres;
+ mSrcBufferInfo->dst_info.canvas_h = mFbInfo->info.yres;
+ mSrcBufferInfo->dst_info.memtype = CANVAS_ALLOC;
+ mSrcBufferInfo->dst_info.rotation = layer[0]->mTransform;
+
+ // ge2d processing.
+ mSrcBufferInfo->ge2d_op = AML_GE2D_BLEND;
+ ge2d_process(mGe2dFd, mSrcBufferInfo);
+
+ if (mDebug) {
+ // ALOGE("hnd[0]->format: 0x%x, hnd[1]->format: 0x%x", hnd[0]->format, hnd[1]->format);
+ // dumpLayers(hnd[0]);
+
+ ALOGE(" same crop");
+ tracer();
+ }
+
+ if (sameSize && layerNum == GE2D_COMPOSE_TWO_LAYERS) return;
+ }
+
+ int32_t beginWith = 0;
+ if (sameSize) {
+ if (layerNum == GE2D_COMPOSE_THREE_LAYERS) {
+ beginWith = GE2D_COMPOSE_THREE_LAYERS -1;
+ }
+ }
+
+ bool canBlend = false;
+ for (int32_t i=beginWith; i<layerNum; i++) {
+ mSrcBufferInfo->blend_mode = layer[i]->mBlendMode;
+ canBlend = Utils::compareSize(sourceCrop[i], displayFrame[i]);
+
+ if (0 == i && !isFullScreen(displayFrame[i])) {
+ hwc_rect_t clipRect;
+ clipRect.left = 0;
+ clipRect.top = 0;
+ clipRect.right = mFbInfo->info.xres;
+ clipRect.bottom = mFbInfo->info.yres;
+ fillRectangle(clipRect, 0, mBasePhyAddr + slot * mFbInfo->finfo.line_length);
+ }
+
+ mSrcBufferInfo->src_info[0].paddr = getIonPhyAddr(mFbInfo, hnd[i]);
+ mSrcBufferInfo->src_info[0].format = hnd[i]->format;
+ mSrcBufferInfo->src_info[0].rect.x = (int32_t)sourceCrop[i].left;
+ mSrcBufferInfo->src_info[0].rect.y = (int32_t)sourceCrop[i].top;
+ if (!canBlend
+ && (hnd[i]->format == HAL_PIXEL_FORMAT_YCrCb_420_SP
+ || hnd[i]->format == HAL_PIXEL_FORMAT_YV12)) {
+ mSrcBufferInfo->src_info[0].rect.w = (int32_t)(sourceCrop[i].right - sourceCrop[i].left);
+ mSrcBufferInfo->src_info[0].rect.h = (int32_t)(sourceCrop[i].bottom- sourceCrop[i].top);
+ } else {
+ mSrcBufferInfo->src_info[0].rect.w = (int32_t)(sourceCrop[i].right - sourceCrop[i].left);
+ mSrcBufferInfo->src_info[0].rect.h = (int32_t)(sourceCrop[i].bottom- sourceCrop[i].top);
+ }
+ mSrcBufferInfo->src_info[0].canvas_w = hnd[i]->stride;
+ mSrcBufferInfo->src_info[0].canvas_h = hnd[i]->height;
+ mSrcBufferInfo->src_info[0].memtype = CANVAS_ALLOC;
+
+ // SRC1 equals DST.
+ mSrcBufferInfo->src_info[1].paddr = mBasePhyAddr + slot * mFbInfo->finfo.line_length;
+ mSrcBufferInfo->src_info[1].format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mSrcBufferInfo->src_info[1].rect.x = displayFrame[i].left;
+ mSrcBufferInfo->src_info[1].rect.y = displayFrame[i].top;
+ mSrcBufferInfo->src_info[1].rect.w = displayFrame[i].right - displayFrame[i].left;
+ mSrcBufferInfo->src_info[1].rect.h = displayFrame[i].bottom - displayFrame[i].top;
+ mSrcBufferInfo->src_info[1].canvas_w = mFbInfo->info.xres;
+ mSrcBufferInfo->src_info[1].canvas_h = mFbInfo->info.yres;
+ mSrcBufferInfo->src_info[1].memtype = CANVAS_ALLOC;
+
+ mSrcBufferInfo->dst_info.paddr = mBasePhyAddr + slot * mFbInfo->finfo.line_length;
+ mSrcBufferInfo->dst_info.format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mSrcBufferInfo->dst_info.rect.x = displayFrame[i].left;
+ mSrcBufferInfo->dst_info.rect.y = displayFrame[i].top;
+ /*mSrcBufferInfo->dst_info.rect.w = displayFrame.right - displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.h = displayFrame.bottom - displayFrame.top;*/
+ mSrcBufferInfo->dst_info.canvas_w = mFbInfo->info.xres;
+ mSrcBufferInfo->dst_info.canvas_h = mFbInfo->info.yres;
+ mSrcBufferInfo->dst_info.memtype = CANVAS_ALLOC;
+
+ mSrcBufferInfo->dst_info.rotation = layer[i]->mTransform;
+
+ // ge2d processing.
+ if (0 == i || !canBlend || BLEND_MODE_INVALID == mSrcBufferInfo->blend_mode) {
+ mSrcBufferInfo->dst_info.rect.w = displayFrame[i].right - displayFrame[i].left;
+ mSrcBufferInfo->dst_info.rect.h = displayFrame[i].bottom - displayFrame[i].top;
+ mSrcBufferInfo->ge2d_op = AML_GE2D_STRETCHBLIT;
+ } else {
+ mSrcBufferInfo->dst_info.rect.w = Utils::min(mSrcBufferInfo->src_info[0].rect.w, mSrcBufferInfo->src_info[1].rect.w);
+ mSrcBufferInfo->dst_info.rect.h = Utils::min(mSrcBufferInfo->src_info[0].rect.h, mSrcBufferInfo->src_info[1].rect.h);
+ mSrcBufferInfo->ge2d_op = AML_GE2D_BLEND;
+ if (mDebug) dumpLayers(hnd[i]);
+ }
+
+ ge2d_process(mGe2dFd, mSrcBufferInfo);
+ if (mDebug) {
+ ALOGE(" layers sameSize is %d", sameSize);
+ tracer();
+ }
+ }
+}
+
+// #define GE2D_PORCESS_TIMESTAMP
+bool GE2DComposer::threadLoop()
+{
+ Mutex::Autolock _l(mLock);
+ mCondition.wait(mLock);
+ if (mExitThread) {
+ ITRACE("exiting thread loop");
+ return false;
+ }
+
+ Fifo::iterator front(mQueueItems.begin());
+ // do ge2d compose.
+ while (mQueuedFrames > 0 && mQueueItems.size() > 0) {
+#ifdef GE2D_PORCESS_TIMESTAMP
+ nsecs_t beforeTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+ // wait all layers fence here.
+ int32_t slot = front->mSlot;
+ int32_t mergedFence = front->mFence;
+ Vector< LayerState* > layersState = front->mLayersState;
+
+ // wait all fence to be signaled here.
+ HwcFenceControl::waitAndCloseFd(mergedFence, 2800);
+
+ // run ge2d process here.
+ runGE2DProcess(slot, layersState);
+
+ // ge2d finished process, make sure fd close here.
+ for (int32_t i=0; i<layersState.size(); i++) {
+ LayerState* layer = layersState.itemAt(i);
+ // ALOGE("close->layer:[%12" PRIxPTR ", %d]", layer->mBufferHnd, layer->mBufferFd);
+ if (layer != NULL) {
+ Utils::closeFd(layer->mBufferFd);
+ layer->mBufferFd = -1;
+ delete layer;
+ }
+ }
+
+#ifdef GE2D_PORCESS_TIMESTAMP
+ nsecs_t afterTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ ALOGE("Ge2d process Period: %" PRId64 "", afterTimeStamp - beforeTimeStamp);
+#endif
+ // usleep(1000*100);
+ // signal ge2d's release fence.
+ HwcFenceControl::syncTimelineInc(mSyncTimelineFd);
+
+ mQueueItems.erase(front);
+ front = mQueueItems.begin();
+ android_atomic_dec(&mQueuedFrames);
+ }
+
+ return true;
+}
+
+} // namespace amlogic
+} // namesapce android
+
diff --git a/hwc2/common/composers/GE2DComposer.cpp_ b/hwc2/common/composers/GE2DComposer.cpp_
new file mode 100644
index 0000000..376fd04
--- a/dev/null
+++ b/hwc2/common/composers/GE2DComposer.cpp_
@@ -0,0 +1,632 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+#include <HwcTrace.h>
+#include <HwcFenceControl.h>
+#include <GE2DComposer.h>
+#include <IDisplayDevice.h>
+#include <inttypes.h>
+
+#define GE2D_PORCESS_DEBUG
+
+namespace android {
+namespace amlogic {
+
+GE2DComposer::GE2DComposer(IDisplayDevice& disp)
+ : Composers(disp),
+ mDisplayDevice(disp),
+ mLock(),
+ mCondition(),
+ mSyncTimelineFd(-1),
+ mBufferMask(0),
+ mNumBuffers(1),
+ mFbSlot(0),
+ mCurGlesFbSlot(-1),
+ mSingleFbSize(0),
+ mGe2dBufHnd(NULL),
+ mSrcBufferInfo(NULL),
+ mExitThread(false),
+ mInitialized(false)
+{
+ mName = "GE2D";
+
+ mQueue.setCapacity(8);
+ mQueue.clear();
+}
+
+GE2DComposer::~GE2DComposer()
+{
+ WARN_IF_NOT_DEINIT();
+}
+
+int32_t GE2DComposer::allocBuffer(private_module_t* module, size_t size, int32_t usage, buffer_handle_t* pHandle)
+{
+ ion_user_handle_t ion_hnd;
+ unsigned char *cpu_ptr = NULL;
+ int32_t shared_fd;
+ int32_t ret;
+ int32_t ion_flags = 0;
+ int32_t lock_state = 0;
+
+#if 1 // no need cache.
+ if ( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
+ {
+ ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
+ }
+#endif
+
+ if (usage & GRALLOC_USAGE_AML_DMA_BUFFER)
+ {
+ ret = ion_alloc(module->ion_client, size, 0, ION_HEAP_CARVEOUT_MASK,
+ ion_flags, &ion_hnd);
+ }
+
+ if ( ret != 0)
+ {
+ ETRACE("Failed to ion_alloc from ion_client:%d", module->ion_client);
+ return -1;
+ }
+
+ ret = ion_share( module->ion_client, ion_hnd, &shared_fd );
+ if ( ret != 0 )
+ {
+ ETRACE( "ion_share( %d ) failed", module->ion_client );
+ if ( 0 != ion_free( module->ion_client, ion_hnd ) )
+ ETRACE( "ion_free( %d ) failed", module->ion_client );
+ return -1;
+ }
+
+ if (!(usage & GRALLOC_USAGE_PROTECTED))
+ {
+ cpu_ptr = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0 );
+
+ if ( MAP_FAILED == cpu_ptr )
+ {
+ ETRACE( "ion_map( %d ) failed", module->ion_client );
+ if ( 0 != ion_free( module->ion_client, ion_hnd ) )
+ ETRACE( "ion_free( %d ) failed", module->ion_client );
+ close( shared_fd );
+ return -1;
+ }
+ lock_state = private_handle_t::LOCK_STATE_MAPPED;
+ }
+
+ private_handle_t *hnd = new private_handle_t( private_handle_t::PRIV_FLAGS_USES_ION /*TODO ion extend*| priv_heap_flag*/, usage, size, cpu_ptr,
+ lock_state );
+
+ if ( NULL != hnd )
+ {
+ hnd->share_fd = shared_fd;
+ hnd->ion_hnd = ion_hnd;
+ /*TODO ion extend hnd->min_pgsz = min_pgsz; */
+ *pHandle = hnd;
+ return 0;
+ }
+ else
+ {
+ ETRACE( "Gralloc out of mem for ion_client:%d", module->ion_client );
+ }
+
+ close( shared_fd );
+
+ if (!(usage & GRALLOC_USAGE_PROTECTED))
+ {
+ ret = munmap( cpu_ptr, size );
+ if ( 0 != ret )
+ ETRACE( "munmap failed for base:%p size: %zd", cpu_ptr, size );
+ }
+
+ ret = ion_free( module->ion_client, ion_hnd );
+ if ( 0 != ret )
+ ETRACE( "ion_free( %d ) failed", module->ion_client );
+ return -1;
+}
+
+void GE2DComposer::freeBuffer(private_handle_t const* hnd, private_module_t* m)
+{
+ if ( hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION )
+ {
+ /* Buffer might be unregistered already so we need to assure we have a valid handle*/
+ if ( 0 != hnd->base )
+ {
+ if ( 0 != munmap( (void*)hnd->base, hnd->size ) ) ETRACE( "Failed to munmap handle %p", hnd );
+ }
+ close( hnd->share_fd );
+ if ( 0 != ion_free( m->ion_client, hnd->ion_hnd ) ) ETRACE( "Failed to ion_free( ion_client: %d ion_hnd: %p )", m->ion_client, hnd->ion_hnd );
+ memset( (void*)hnd, 0, sizeof( *hnd ) );
+ }
+}
+
+bool GE2DComposer::initialize(framebuffer_info_t* fbInfo)
+{
+ Mutex::Autolock _l(mLock);
+
+ if (mInitialized) {
+ WTRACE("object has been initialized");
+ return true;
+ }
+
+ // create a release fence timeline.
+ mSyncTimelineFd = HwcFenceControl::createFenceTimeline();
+ if (mSyncTimelineFd == -1) {
+ DEINIT_AND_RETURN_FALSE("sync timeline create failed!");
+ }
+ mCurrentSyncTime = 1;
+
+ // create ge2d composer thread.
+ mExitThread = false;
+ mThread = new GE2DRenderThread(this);
+ if (!mThread.get()) {
+ DEINIT_AND_RETURN_FALSE("failed to create ge2d composer thread.");
+ }
+ mThread->run("GE2DComposer", PRIORITY_URGENT_DISPLAY);
+
+ // framebuffer stuff.
+ mFbInfo = fbInfo;
+ mSingleFbSize = fbInfo->finfo.line_length
+ * fbInfo->info.yres;
+ mNumBuffers = fbInfo->fbSize / mSingleFbSize;
+
+ mSrcBufferInfo = new aml_ge2d_info_t();
+
+ // ge2d init.
+ ge2d_init();
+ mInitialized = true;
+ return true;
+}
+
+void GE2DComposer::deinitialize()
+{
+ mExitThread = true;
+ mCondition.signal();
+
+ if (mThread.get()) {
+ mThread->requestExitAndWait();
+ mThread = NULL;
+ }
+
+ if (mSrcBufferInfo != NULL) {
+ delete mSrcBufferInfo;
+ mSrcBufferInfo = NULL;
+ }
+
+ // ge2d exit.
+ ge2d_exit();
+ mInitialized = false;
+}
+
+const char* GE2DComposer::getName() const
+{
+ return mName;
+}
+
+const uint32_t GE2DComposer::getFbSlot()
+{
+ Mutex::Autolock _l(mLock);
+
+ return mFbSlot;
+}
+
+void GE2DComposer::setCurGlesFbSlot(uint32_t slot) {
+ Mutex::Autolock _l(mLock);
+
+ mCurGlesFbSlot = slot;
+}
+
+uint32_t GE2DComposer::findFreeFbSlot()
+{
+ int32_t fbSlot = 0;
+
+ if (mNumBuffers == 1) {
+ // If we have only one buffer, we never use page-flipping.
+ return 0;
+ }
+
+ if (-1 != mCurGlesFbSlot) {
+ // mBufferMask = 0x0;
+ // If gles composer just before come here, we should avoid this buffer and prior buffer.
+ fbSlot = mCurGlesFbSlot + 2 * mFbInfo->info.yres;
+ if (fbSlot % (3*mFbInfo->info.yres) == 0) {
+ mBufferMask = 0x1;
+ } else if (fbSlot % (3*mFbInfo->info.yres) == 1) {
+ mBufferMask = 0x7;
+ } else if (fbSlot % (3*mFbInfo->info.yres) == 2) {
+ mBufferMask = 0x3;
+ }
+
+ /*for (uint32_t i= 0; i<(fbSlot % (3*mFbInfo->info.yres)) / mFbInfo->info.yres + 1; i++) {
+ mBufferMask |= (1LU<<i);
+ }*/
+ mCurGlesFbSlot = -1;
+ ETRACE("Stark, mNumBuffers: %d, mBufferMask: 0x%x", mNumBuffers, mBufferMask);
+ } else {
+ if (mBufferMask >= ((1LU<<mNumBuffers)-1)) {
+ // We ran out of buffers. reinit to 0;
+ mBufferMask = 0x1;
+ return 0;
+ }
+
+ // find a free slot
+ for (uint32_t i=0 ; i<mNumBuffers ; i++) {
+ if ((mBufferMask & (1LU<<i)) == 0) {
+ mBufferMask |= (1LU<<i);
+ break;
+ }
+
+ fbSlot += 2 * mFbInfo->info.yres;
+ }
+ }
+
+ return fbSlot % (3*mFbInfo->info.yres);
+}
+
+int32_t GE2DComposer::startCompose(Vector< hwc2_layer_t > hwcLayers, int32_t *offset)
+{
+ Mutex::Autolock _l(mLock);
+ if (NULL != mGe2dBuffer) {
+ int32_t usage = GRALLOC_USAGE_AML_DMA_BUFFER;
+ int32_t ret = allocBuffer(mFbInfo->grallocModule, mFbInfo->fbSize, usage, &mGe2dBufHnd);
+ if (ret < 0) {
+ ETRACE("allocBuffer failed!");
+ return ALLOC_BUFFER_FAILED;
+ }
+ } else {
+ DTRACE("Buffer alloced already.");
+ }
+
+ // find a free slot of fb.
+ mFbSlot = findFreeFbSlot();
+ *offset = mFbSlot;
+
+ // add hwcLayers to work queue.
+ mQueue.push_back(hwcLayers);
+
+ int32_t ge2dFence = HwcFenceControl::createFence(mSyncTimelineFd, "ge2d_flag", mCurrentSyncTime++);
+ int32_t layersMergedFence = -1;
+ int32_t ge2dMergedFence = -1;
+
+ // wait all layers fence here.
+ for (uint32_t i=0; i<hwcLayers.size(); i++) {
+ hwc2_layer_t layerId = hwcLayers.itemAt(i);
+ HwcLayer* hwcLayer = mDisplayDevice.getLayerById(layerId);
+ if (hwcLayer != NULL) {
+ int32_t duppedFence = hwcLayer->getDuppedAcquireFence();
+ int32_t tempFence = -1;
+
+ tempFence = HwcFenceControl::merge(String8("layers_merged"), duppedFence, layersMergedFence);
+ HwcFenceControl::closeFd(layersMergedFence);
+ layersMergedFence = tempFence;
+
+ // wait layers to be drawed here.
+ HwcFenceControl::waitAndCloseFd(duppedFence, 5000);
+ // HwcFenceControl::closeFd(duppedFence);
+ }
+ }
+ mCondition.signal();
+
+ // merge layer's fences and ge2d fence.
+ ge2dMergedFence = HwcFenceControl::merge(String8("ge2d_flag"), layersMergedFence, ge2dFence);
+ DTRACE("ge2d merged fence: %d", ge2dMergedFence);
+
+ HwcFenceControl::closeFd(ge2dFence);
+ HwcFenceControl::closeFd(layersMergedFence);
+
+ return ge2dMergedFence;
+}
+
+// test.
+void GE2DComposer::directMemcpy(Fifo::iterator front)
+{
+ uintptr_t buffer = (uintptr_t)mFbInfo->grallocModule->fb_primary.framebuffer->base;
+
+ // ge2d work here.
+ for (uint32_t i=0; i<front->size(); i++) {
+ // do ge2d compose.
+ hwc2_layer_t layerId = front->itemAt(i);
+ HwcLayer* hwcLayer = mDisplayDevice.getLayerById(layerId);
+ ETRACE("thread loop to do ge2d work here.");
+
+ if (hwcLayer != NULL) {
+ // video overlay.
+ private_handle_t const* hnd =
+ reinterpret_cast<private_handle_t const*>(hwcLayer->getBufferHandle());
+ if (hnd != NULL) {
+ // common memcpy mode.
+ if (private_handle_t::validate(hnd) < 0) {
+ ETRACE("invalid layer handle.");
+ continue;
+ }
+ void* fBuffer = (void*)(buffer + mSingleFbSize * (mFbSlot/mFbInfo->info.yres));
+ ETRACE("hnd->stride is %d, hnd->height is %d, hnd->size: %d, hnd->base: 0x%llx, mSingleFbSize: %d, Slot: %d, buffer: 0x%llx",
+ hnd->stride, hnd->height, hnd->size, (uintptr_t)hnd->base, mSingleFbSize, mFbSlot/mFbInfo->info.yres, (uintptr_t)fBuffer);
+ if (fBuffer != MAP_FAILED) {
+ memset(fBuffer, 0, mSingleFbSize);
+ memcpy(fBuffer, hnd->base, hnd->size);
+ ETRACE("copy ok");
+ } else {
+ ETRACE("buffer mmap fail");
+ }
+ }
+ }
+ }
+}
+
+#if 0
+void GE2DComposer::runGE2DProcess(HwcLayer* hwcLayer)
+{
+ // ge2d work here.
+ DTRACE("thread loop to do ge2d work here.");
+ hwc_frect_t sourceCrop;
+ hwc_rect_t displayFrame;
+ private_handle_t const* hnd =
+ reinterpret_cast<private_handle_t const*>(hwcLayer->getBufferHandle());
+ if (hnd != NULL) {
+ sourceCrop = hwcLayer->getSourceCrop();
+ displayFrame = hwcLayer->getDisplayFrame();
+
+ mSrcBufferInfo->src_info[0].paddr = getIonPhyAddr(mFbInfo, hnd);
+ mSrcBufferInfo->src_info[0].format = hnd->format;
+ // mSrcBufferInfo->src_info[0].rotation = hwcLayer->getTransform();
+
+ mSrcBufferInfo->src_info[0].rect.x = (int)sourceCrop.left;
+ mSrcBufferInfo->src_info[0].rect.y = (int)sourceCrop.top;
+ mSrcBufferInfo->src_info[0].rect.w = (int)(sourceCrop.right - displayFrame.left);
+ mSrcBufferInfo->src_info[0].rect.h = (int)(sourceCrop.bottom- displayFrame.top);
+ mSrcBufferInfo->src_info[0].canvas_w = hnd->stride;
+ mSrcBufferInfo->src_info[0].canvas_h = hnd->height;
+
+ mSrcBufferInfo->src_info[0].memtype = CANVAS_ALLOC;
+
+ // src1 equals dst.
+ mSrcBufferInfo->src_info[1].rect.x = 0;
+ mSrcBufferInfo->src_info[1].rect.y = 0;
+ mSrcBufferInfo->src_info[1].rect.w = mFbInfo->info.xres;
+ mSrcBufferInfo->src_info[1].rect.h = mFbInfo->info.yres;
+ mSrcBufferInfo->src_info[1].memtype = CANVAS_OSD0;
+
+ mSrcBufferInfo->blend_mode = hwcLayer->getBlendMode();
+
+ mSrcBufferInfo->dst_info.rect.x = displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.y = displayFrame.top;
+ mSrcBufferInfo->dst_info.rect.w = displayFrame.right - displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.h = displayFrame.bottom - displayFrame.top;
+ mSrcBufferInfo->dst_info.memtype = CANVAS_OSD0;
+ mSrcBufferInfo->dst_info.rotation = hwcLayer->getTransform();
+ }
+
+ // ge2d processing.
+ if (0 == mSrcBufferInfo->blend_mode)
+ mSrcBufferInfo->ge2d_op = AML_GE2D_STRETCHBLIT;
+ else
+ mSrcBufferInfo->ge2d_op = AML_GE2D_BLEND;
+
+#ifdef GE2D_PORCESS_DEBUG
+ nsecs_t beforeTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+ ge2d_process(mSrcBufferInfo);
+#ifdef GE2D_PORCESS_DEBUG
+ nsecs_t afterTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ ETRACE("ge2d process Period: %" PRId64 "", afterTimeStamp - beforeTimeStamp);
+ ETRACE("Src1 stride is %d, height is %d, Slot: %d, format: %d, blendMode: %d, "
+ "srcCrop: [%d, %d, %d, %d], displayFrame:[%d, %d, %d, %d]",
+ mSrcBufferInfo->src_info[0].canvas_w, mSrcBufferInfo->src_info[0].canvas_h,
+ mSrcBufferInfo->offset, mSrcBufferInfo->src_info[0].format, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->src_info[0].rect.x, mSrcBufferInfo->src_info[0].rect.y,mSrcBufferInfo->src_info[0].rect.w,mSrcBufferInfo->src_info[0].rect.h,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y, mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+ ETRACE("Src2 stride is %d, height is %d, Slot: %d, format: %d, blendMode: %d, "
+ "srcCrop: [%d, %d, %d, %d], displayFrame:[%d, %d, %d, %d]",
+ mSrcBufferInfo->src_info[1].canvas_w, mSrcBufferInfo->src_info[1].canvas_h,
+ mSrcBufferInfo->offset, mSrcBufferInfo->src_info[1].format, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->src_info[1].rect.x, mSrcBufferInfo->src_info[1].rect.y,mSrcBufferInfo->src_info[1].rect.w,mSrcBufferInfo->src_info[1].rect.h,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y, mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+#endif
+}
+
+#else
+void GE2DComposer::runGE2DProcess(HwcLayer* hwcLayer1, HwcLayer* hwcLayer2)
+{
+ bool sameSourceCrop = false;
+ bool swapLayers = false;
+ hwc_frect_t sourceCrop[2];
+ HwcLayer* layer[2];
+ private_handle_t const* hnd[2];
+ nsecs_t beforeTimeStamp = 0, afterTimeStamp = 0;
+ hwc_rect_t displayFrame;
+ uint32_t layerNum = GE2D_COMPOSE_ONE_LAYER;
+
+ layer[0] = hwcLayer1;
+ layer[1] = hwcLayer2;
+
+ if (layer[1] != NULL) {
+ layerNum = GE2D_COMPOSE_TWO_LAYERS;
+ sourceCrop[0] = layer[0]->getSourceCrop();
+ sourceCrop[1] = layer[1]->getSourceCrop();
+ if ((int32_t)sourceCrop[0].left == (int32_t)sourceCrop[1].left
+ && (int32_t)sourceCrop[0].top == (int32_t)sourceCrop[1].top
+ && (int32_t)sourceCrop[0].right == (int32_t)sourceCrop[1].right
+ && (int32_t)sourceCrop[0].bottom == (int32_t)sourceCrop[1].bottom) {
+ sameSourceCrop = true;
+ }
+
+ if (sameSourceCrop && 0 != layer[1]->getBlendMode() && 0 == layer[0]->getBlendMode()) {
+ layer[0] = hwcLayer2;
+ layer[1] = hwcLayer1;
+ swapLayers = true;
+ }
+ }
+
+ for (int32_t i=0; i<layerNum; i++) {
+ hnd[i] = reinterpret_cast<private_handle_t const*>(layer[i]->getBufferHandle());
+ }
+
+ if (sameSourceCrop && swapLayers) {
+ if (hnd[0] != NULL && hnd[1] != NULL) {
+ for (int32_t i=0; i<layerNum; i++) {
+ ETRACE("hnds: %p, %p", hnd[0], hnd[1]);
+ mSrcBufferInfo->src_info[i].paddr = getIonPhyAddr(mFbInfo, hnd[i]);
+ mSrcBufferInfo->src_info[i].format = hnd[i]->format;
+ mSrcBufferInfo->src_info[i].rect.x = (int32_t)sourceCrop[i].left;
+ mSrcBufferInfo->src_info[i].rect.y = (int32_t)sourceCrop[i].top;
+ mSrcBufferInfo->src_info[i].rect.w = (int32_t)(sourceCrop[i].right - sourceCrop[i].left);
+ mSrcBufferInfo->src_info[i].rect.h = (int32_t)(sourceCrop[i].bottom- sourceCrop[i].top);
+ mSrcBufferInfo->src_info[i].canvas_w = hnd[i]->stride;
+ mSrcBufferInfo->src_info[i].canvas_h = hnd[i]->height;
+ mSrcBufferInfo->src_info[i].memtype = CANVAS_ALLOC;
+ }
+ mSrcBufferInfo->blend_mode = layer[0]->getBlendMode();
+ displayFrame = layer[0]->getDisplayFrame();
+
+ mSrcBufferInfo->dst_info.rect.x = displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.y = displayFrame.top;
+ mSrcBufferInfo->dst_info.rect.w = displayFrame.right - displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.h = displayFrame.bottom - displayFrame.top;
+ mSrcBufferInfo->dst_info.memtype = CANVAS_OSD0;
+ }
+ mSrcBufferInfo->dst_info.rotation = layer[0]->getTransform();
+
+ // ge2d processing.
+ mSrcBufferInfo->ge2d_op = AML_GE2D_BLEND;
+#ifdef GE2D_PORCESS_DEBUG
+ nsecs_t beforeTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+ ge2d_process(mSrcBufferInfo);
+#ifdef GE2D_PORCESS_DEBUG
+ nsecs_t afterTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ ETRACE("Same SourceCrop ge2d process Period: %" PRId64 "", afterTimeStamp - beforeTimeStamp);
+
+ ETRACE("Same SourceCrop Src1 stride is %d, height is %d, Slot: %d, format: %d, blendMode: %d, "
+ "srcCrop: [%d, %d, %d, %d], displayFrame:[%d, %d, %d, %d]",
+ mSrcBufferInfo->src_info[0].canvas_w, mSrcBufferInfo->src_info[0].canvas_h,
+ mSrcBufferInfo->offset, mSrcBufferInfo->src_info[0].format, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->src_info[0].rect.x, mSrcBufferInfo->src_info[0].rect.y,mSrcBufferInfo->src_info[0].rect.w,mSrcBufferInfo->src_info[0].rect.h,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y, mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+ ETRACE("Same SourceCrop Src2 stride is %d, height is %d, Slot: %d, format: %d, blendMode: %d, "
+ "srcCrop: [%d, %d, %d, %d], displayFrame:[%d, %d, %d, %d]",
+ mSrcBufferInfo->src_info[1].canvas_w, mSrcBufferInfo->src_info[1].canvas_h,
+ mSrcBufferInfo->offset, mSrcBufferInfo->src_info[1].format, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->src_info[1].rect.x, mSrcBufferInfo->src_info[1].rect.y,mSrcBufferInfo->src_info[1].rect.w,mSrcBufferInfo->src_info[1].rect.h,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y, mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+#endif
+ } else {
+ if (layerNum == GE2D_COMPOSE_TWO_LAYERS && hnd[1] == NULL) {
+ ETRACE("two layers compose, hnd should not be null");
+ return;
+ }
+ for (int32_t i=0; i<layerNum; i++) {
+ mSrcBufferInfo->src_info[0].paddr = getIonPhyAddr(mFbInfo, hnd[i]);
+ mSrcBufferInfo->src_info[0].format = hnd[i]->format;
+ mSrcBufferInfo->src_info[0].rect.x = (int32_t)sourceCrop[i].left;
+ mSrcBufferInfo->src_info[0].rect.y = (int32_t)sourceCrop[i].top;
+ mSrcBufferInfo->src_info[0].rect.w = (int32_t)(sourceCrop[i].right - sourceCrop[i].left);
+ mSrcBufferInfo->src_info[0].rect.h = (int32_t)(sourceCrop[i].bottom- sourceCrop[i].top);
+ mSrcBufferInfo->src_info[0].canvas_w = hnd[i]->stride;
+ mSrcBufferInfo->src_info[0].canvas_h = hnd[i]->height;
+ mSrcBufferInfo->src_info[0].memtype = CANVAS_ALLOC;
+
+ // src1 equals dst.
+ mSrcBufferInfo->src_info[1].rect.x = 0;
+ mSrcBufferInfo->src_info[1].rect.y = 0;
+ mSrcBufferInfo->src_info[1].rect.w = mFbInfo->info.xres;
+ mSrcBufferInfo->src_info[1].rect.h = mFbInfo->info.yres;
+ mSrcBufferInfo->src_info[1].memtype = CANVAS_OSD0;
+ mSrcBufferInfo->blend_mode = layer[i]->getBlendMode();
+
+ displayFrame = layer[i]->getDisplayFrame();
+ mSrcBufferInfo->dst_info.rect.x = displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.y = displayFrame.top;
+ mSrcBufferInfo->dst_info.rect.w = displayFrame.right - displayFrame.left;
+ mSrcBufferInfo->dst_info.rect.h = displayFrame.bottom - displayFrame.top;
+ mSrcBufferInfo->dst_info.memtype = CANVAS_OSD0;
+ mSrcBufferInfo->dst_info.rotation = layer[i]->getTransform();
+
+ // ge2d processing.
+ if (0 == mSrcBufferInfo->blend_mode)
+ mSrcBufferInfo->ge2d_op = AML_GE2D_STRETCHBLIT;
+ else
+ mSrcBufferInfo->ge2d_op = AML_GE2D_BLEND;
+#ifdef GE2D_PORCESS_DEBUG
+ nsecs_t beforeTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+ ge2d_process(mSrcBufferInfo);
+#ifdef GE2D_PORCESS_DEBUG
+ nsecs_t afterTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ ETRACE("Ge2d process Period: %" PRId64 "", afterTimeStamp - beforeTimeStamp);
+ ETRACE("Src1 stride is %d, height is %d, Slot: %d, format: %d, blendMode: %d, "
+ "srcCrop: [%d, %d, %d, %d], displayFrame:[%d, %d, %d, %d]",
+ mSrcBufferInfo->src_info[0].canvas_w, mSrcBufferInfo->src_info[0].canvas_h,
+ mSrcBufferInfo->offset, mSrcBufferInfo->src_info[0].format, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->src_info[0].rect.x, mSrcBufferInfo->src_info[0].rect.y,mSrcBufferInfo->src_info[0].rect.w,mSrcBufferInfo->src_info[0].rect.h,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y, mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+ ETRACE("Src2 stride is %d, height is %d, Slot: %d, format: %d, blendMode: %d, "
+ "srcCrop: [%d, %d, %d, %d], displayFrame:[%d, %d, %d, %d]",
+ mSrcBufferInfo->src_info[1].canvas_w, mSrcBufferInfo->src_info[1].canvas_h,
+ mSrcBufferInfo->offset, mSrcBufferInfo->src_info[1].format, mSrcBufferInfo->blend_mode,
+ mSrcBufferInfo->src_info[1].rect.x, mSrcBufferInfo->src_info[1].rect.y,mSrcBufferInfo->src_info[1].rect.w,mSrcBufferInfo->src_info[1].rect.h,
+ mSrcBufferInfo->dst_info.rect.x, mSrcBufferInfo->dst_info.rect.y, mSrcBufferInfo->dst_info.rect.w, mSrcBufferInfo->dst_info.rect.h);
+#endif
+ }
+ }
+}
+#endif
+
+bool GE2DComposer::threadLoop()
+{
+ Mutex::Autolock _l(mLock);
+ mCondition.wait(mLock);
+ if (mExitThread) {
+ ITRACE("exiting thread loop");
+ return false;
+ }
+
+ DTRACE("Stark, sync timeline fd : %d", mSyncTimelineFd);
+ Fifo::iterator front(mQueue.begin());
+ while (mQueue.size() > 0) {
+ // direct memcpy mode test.
+ // directMemcpy(front);
+
+ // do ge2d compose.
+ // ETRACE("thread loop to do ge2d work here.");
+ hwc2_layer_t layerId = front->itemAt(0);
+ HwcLayer* hwcLayer = mDisplayDevice.getLayerById(layerId);
+ switch (front->size()) {
+ case GE2D_COMPOSE_ONE_LAYER:
+ {
+ // run one layer ge2d process.
+ if (hwcLayer != NULL) {
+ mSrcBufferInfo->offset = mFbSlot;
+ runGE2DProcess(hwcLayer, NULL);
+ }
+ }
+ break;
+ case GE2D_COMPOSE_TWO_LAYERS:
+ {
+ // run 2 layers ge2d process.
+ hwc2_layer_t layerId2 = front->itemAt(1);
+ HwcLayer* hwcLayer2 = mDisplayDevice.getLayerById(layerId2);
+
+ // run two layers ge2d process.
+ if (hwcLayer != NULL && hwcLayer2 != NULL) {
+ mSrcBufferInfo->offset = mFbSlot;
+ runGE2DProcess(hwcLayer, hwcLayer2);
+ }
+ }
+ break;
+ case GE2D_COMPOSE_THREE_LAYERS:
+ default:
+ ETRACE("More than 2 layers exists, ge2d can't do that process!");
+ break;
+ }
+
+ // signal ge2d's release fence.
+ HwcFenceControl::syncTimelineInc(mSyncTimelineFd);
+
+ mQueue.erase(front);
+ front = mQueue.begin();
+ }
+
+ return true;
+}
+
+} // namespace amlogic
+} // namesapce android
+
diff --git a/hwc2/common/composers/GE2DComposer.h b/hwc2/common/composers/GE2DComposer.h
new file mode 100644
index 0000000..509252f
--- a/dev/null
+++ b/hwc2/common/composers/GE2DComposer.h
@@ -0,0 +1,169 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+
+#ifndef GE2D_COMPOSER_H
+#define GE2D_COMPOSER_H
+
+#include <utils/KeyedVector.h>
+#include <SimpleThread.h>
+#include <Composers.h>
+#include <IDisplayDevice.h>
+#include <inttypes.h>
+
+#include <ge2d_port.h>
+#include <../kernel-headers/linux/ge2d.h>
+
+namespace android {
+namespace amlogic {
+
+class LayerState {
+public:
+ LayerState()
+ : mBufferHnd(NULL),
+ mBlendMode(0),
+ mTransform(HAL_TRANSFORM_RESERVED),
+ mBufferFd(-1) {
+ }
+
+ ~LayerState() {
+ }
+
+ //void setLayerState(HwcLayer* hwcLayer);
+ void setLayerState(HwcLayer* hwcLayer) {
+ mBlendMode = hwcLayer->getBlendMode();
+ mColor = hwcLayer->getColor();
+ mCompositionType = hwcLayer->getCompositionType();
+ mAcquireFence = hwcLayer->getAcquireFence();
+ mDataSpace = hwcLayer->getDataspace();
+ mPlaneAlpha = hwcLayer->getPlaneAlpha();
+ mTransform = hwcLayer->getTransform();
+ mZ = hwcLayer->getZ();
+ mSourceCrop = hwcLayer->getSourceCrop();
+ mDisplayFrame = hwcLayer->getDisplayFrame();
+ mBufferHnd = hwcLayer->getBufferHandle();
+
+ private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(mBufferHnd);
+ mBufferFd = Utils::checkAndDupFd(hnd->ion_hnd);
+ }
+
+ int32_t mBlendMode;
+ hwc_color_t mColor;
+ int32_t mCompositionType;
+ int32_t mAcquireFence;
+ int32_t mDataSpace;
+ float mPlaneAlpha;
+ int32_t mTransform;
+ uint32_t mZ;
+ hwc_frect_t mSourceCrop;
+ hwc_rect_t mDisplayFrame;
+ // hwc_region_t mDamageRegion;
+ hwc_region_t mVisibleRegion;
+
+ buffer_handle_t mBufferHnd;
+
+ // hold this until ge2d finish process.
+ int32_t mBufferFd;
+};
+
+class SlotInfo {
+public:
+ SlotInfo()
+ : mSlot(-1),
+ mFence(-1),
+ mLayersState() {
+ mLayersState.setCapacity(GE2D_COMPOSE_MAX_LAYERS);
+ mLayersState.clear();
+ }
+
+ ~SlotInfo() {
+ }
+
+ const int32_t getSlot() const { return mSlot; };
+ const int32_t getMergedFence() const { return mFence; };
+ const Vector< LayerState* > getLayersState() const { return mLayersState; };
+
+ int32_t mSlot;
+ int32_t mFence;
+ Vector< LayerState* > mLayersState;
+};
+
+enum { NUM_GE2D_BUFFER_SLOTS = 3 };
+
+class IDisplayDevice;
+
+class GE2DComposer : public Composers {
+
+public:
+ GE2DComposer(IDisplayDevice& disp);
+ virtual ~GE2DComposer();
+
+public:
+ typedef Vector< SlotInfo > Fifo;
+
+ virtual bool initialize(framebuffer_info_t* fbInfo);
+ virtual void deinitialize();
+ virtual const char* getName() const;
+ virtual int32_t startCompose(Vector< hwc2_layer_t > hwcLayers, int32_t *offset = 0, int32_t frameCount = 0);
+ // virtual void setCurGlesFbSlot(uint32_t slot);
+ virtual const buffer_handle_t getBufHnd();
+ virtual void mergeRetireFence(int32_t slot, int32_t retireFence);
+ virtual void removeRetireFence(int32_t slot);
+ virtual void setVideoOverlayLayerId(hwc2_layer_t layerId);
+ virtual void fillRectangle(hwc_rect_t clipRect, uint32_t color, uint32_t addr);
+private:
+ uint32_t findFreeFbSlot();
+ void runGE2DProcess(int32_t slot, Vector< LayerState* > &hwcLayersState);
+ void directMemcpy(Fifo::iterator front); // test.
+ int32_t allocBuffer(private_module_t* module, size_t size, int32_t usage, buffer_handle_t* pHandle);
+ void freeBuffer(private_handle_t const* hnd, private_module_t* m);
+ bool isFullScreen(hwc_rect_t displayFrame);
+ void tracer();
+ void dumpLayers(private_handle_t const* hnd);
+
+
+ IDisplayDevice& mDisplayDevice;
+ const char* mName;
+
+ // Thread safe, mQueueItems is a FIFO of queued work used in synchronous mode.
+ volatile int32_t mQueuedFrames;
+ Fifo mQueueItems;
+
+ // Fence.
+ int32_t mSyncTimelineFd;
+ uint32_t mCurrentSyncTime;
+
+ int32_t mBufferMask;
+ int32_t mNumBuffers;
+ SlotInfo mSlots[NUM_GE2D_BUFFER_SLOTS];
+ hwc2_layer_t mVideoLayerId;
+ // LayerState mVideoLayerState;
+ int32_t mFbSlot;
+ int32_t mCurGlesFbSlot;
+ framebuffer_info_t* mFbInfo;
+ int32_t mSingleFbSize;
+
+ buffer_handle_t mGe2dBufHnd;
+ uint32_t mBasePhyAddr;
+ int32_t mGe2dFd;
+
+ aml_ge2d_info_t *mSrcBufferInfo;
+ bool mDebug;
+
+ int32_t mDevice;
+ mutable Mutex mLock;
+ Condition mCondition;
+ bool mExitThread;
+ bool mInitialized;
+
+private:
+ DECLARE_THREAD(GE2DRenderThread, GE2DComposer);
+};
+
+} // namespace amlogic
+} // namespace android
+
+
+
+#endif /* GE2D_COMPOSITOR_H */
+
diff --git a/hwc2/common/composers/GE2DComposer.h_ b/hwc2/common/composers/GE2DComposer.h_
new file mode 100644
index 0000000..707e8bb
--- a/dev/null
+++ b/hwc2/common/composers/GE2DComposer.h_
@@ -0,0 +1,80 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+
+#ifndef GE2D_COMPOSER_H
+#define GE2D_COMPOSER_H
+
+#include <utils/KeyedVector.h>
+#include <SimpleThread.h>
+#include <Composers.h>
+
+#include <ge2d/include_aml/ge2d_port.h>
+#include <ge2d/include_aml/ge2d.h>
+// #include <ge2d/aml_ge2d.h>
+
+namespace android {
+namespace amlogic {
+
+class IDisplayDevice;
+
+class GE2DComposer : public Composers {
+public:
+ GE2DComposer(IDisplayDevice& disp);
+ virtual ~GE2DComposer();
+
+public:
+ typedef Vector< Vector< hwc2_layer_t > > Fifo;
+
+ virtual bool initialize(framebuffer_info_t* fbInfo);
+ virtual void deinitialize();
+ virtual const char* getName() const;
+ virtual int32_t startCompose(Vector< hwc2_layer_t > hwcLayers, int32_t *offset = 0);
+ virtual void setCurGlesFbSlot(uint32_t slot);
+ virtual const uint32_t getFbSlot();
+
+private:
+ uint32_t findFreeFbSlot();
+ void runGE2DProcess(HwcLayer* hwcLayer1, HwcLayer* hwcLayer2);
+ void directMemcpy(Fifo::iterator front); // test.
+
+ IDisplayDevice& mDisplayDevice;
+ const char* mName;
+
+ // mQueue is a FIFO of queued work used in synchronous mode.
+ Fifo mQueue;
+
+ // Fence.
+ int32_t mSyncTimelineFd;
+ uint32_t mCurrentSyncTime;
+
+ int32_t mBufferMask;
+ int32_t mNumBuffers;
+ int32_t mFbSlot;
+ int32_t mCurGlesFbSlot;
+ framebuffer_info_t* mFbInfo;
+ int32_t mSingleFbSize;
+ buffer_handle_t mGe2dBufHnd;
+
+ // ge2d target buffer info.
+ // buffer_info_t *mTargetBufferInfo;
+ // ge2d src buffer info.
+ aml_ge2d_info_t *mSrcBufferInfo;
+
+ int32_t mDevice;
+ mutable Mutex mLock;
+ Condition mCondition;
+ bool mExitThread;
+ bool mInitialized;
+
+private:
+ DECLARE_THREAD(GE2DRenderThread, GE2DComposer);
+};
+
+} // namespace amlogic
+} // namespace android
+
+
+
+#endif /* GE2D_COMPOSITOR_H */
+
diff --git a/hwc2/common/devices/ExternalDevice.cpp b/hwc2/common/devices/ExternalDevice.cpp
index b56f60a..c01e9f9 100644
--- a/hwc2/common/devices/ExternalDevice.cpp
+++ b/hwc2/common/devices/ExternalDevice.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <HwcTrace.h>
diff --git a/hwc2/common/devices/PhysicalDevice.cpp b/hwc2/common/devices/PhysicalDevice.cpp
index e4f6ab2..e9d61bd 100644
--- a/hwc2/common/devices/PhysicalDevice.cpp
+++ b/hwc2/common/devices/PhysicalDevice.cpp
@@ -1,14 +1,29 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#include <fcntl.h>
+#include <inttypes.h>
#include <HwcTrace.h>
#include <PhysicalDevice.h>
#include <Hwcomposer.h>
#include <sys/ioctl.h>
#include <sync/sync.h>
#include <Utils.h>
-
+#include <HwcFenceControl.h>
+#include <cutils/properties.h>
#include <tvp/OmxUtil.h>
static int Amvideo_Handle = 0;
@@ -16,17 +31,26 @@ static int Amvideo_Handle = 0;
namespace android {
namespace amlogic {
-PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc)
+PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControlFactory* controlFactory)
: mId(id),
mHwc(hwc),
+ mControlFactory(controlFactory),
mActiveDisplayConfig(-1),
mVsyncObserver(NULL),
mIsConnected(false),
mFramebufferHnd(NULL),
- mFramebufferInfo(NULL),
+ mFbSlot(0),
+ mComposer(NULL),
mPriorFrameRetireFence(-1),
+ mClientTargetHnd(NULL),
mTargetAcquireFence(-1),
+ mRenderMode(GLES_COMPOSE_MODE),
mIsValidated(false),
+ mDirectRenderLayerId(0),
+ mVideoOverlayLayerId(0),
+ mGE2DClearVideoRegionCount(0),
+ mOSD0Blank(false),
+ mGE2DComposeFrameCount(0),
mInitialized(false)
{
CTRACE();
@@ -53,11 +77,18 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc)
// set capacity of mDisplayConfigs
mDisplayConfigs.setCapacity(DEVICE_COUNT);
+
+ mGE2DRenderSortedLayerIds.setCapacity(GE2D_COMPOSE_MAX_LAYERS);
+ mGE2DRenderSortedLayerIds.clear();
+
+ mHwcCurReleaseFences = mHwcPriorReleaseFences = NULL;
}
PhysicalDevice::~PhysicalDevice()
{
WARN_IF_NOT_DEINIT();
+ clearFenceList(mHwcCurReleaseFences);
+ clearFenceList(mHwcPriorReleaseFences);
}
bool PhysicalDevice::initialize() {
@@ -82,16 +113,32 @@ void PhysicalDevice::deinitialize() {
Mutex::Autolock _l(mLock);
DEINIT_AND_DELETE_OBJ(mVsyncObserver);
+ DEINIT_AND_DELETE_OBJ(mComposer);
+
+ if (mFramebufferContext != NULL) {
+ delete mFramebufferContext;
+ mFramebufferContext = NULL;
+ }
+
+ if (mCursorContext != NULL) {
+ delete mCursorContext;
+ mCursorContext = NULL;
+ }
mInitialized = false;
}
HwcLayer* PhysicalDevice::getLayerById(hwc2_layer_t layerId) {
HwcLayer* layer = NULL;
+ ssize_t index = mHwcLayers.indexOfKey(layerId);
- layer = mHwcLayers.valueFor(layerId);
- if (!layer) ETRACE("getLayerById %lld error!", layerId);
+ if (index >= 0) {
+ layer = mHwcLayers.valueFor(layerId);
+ }
+ if (!layer) {
+ DTRACE("getLayerById %lld error!", layerId);
+ }
return layer;
}
@@ -103,14 +150,14 @@ int32_t PhysicalDevice::acceptDisplayChanges() {
layer = mHwcLayersChangeType.valueAt(i);
if (layer) {
if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE
- || layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
+ || layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
layer->setCompositionType(HWC2_COMPOSITION_CLIENT);
} else if (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND) {
layer->setCompositionType(HWC2_COMPOSITION_DEVICE);
}
}
}
- // reset layer changed or requested to zero.
+ // reset layer changed or requested size to zero.
mHwcLayersChangeType.clear();
mHwcLayersChangeRequest.clear();
@@ -128,6 +175,7 @@ bool PhysicalDevice::createLayer(hwc2_layer_t* outLayer) {
hwc2_layer_t layerId = reinterpret_cast<hwc2_layer_t>(layer);
mHwcLayers.add(layerId, layer);
*outLayer = layerId;
+ ETRACE("layerId %lld.\n", layerId);
return true;
}
@@ -140,6 +188,15 @@ bool PhysicalDevice::destroyLayer(hwc2_layer_t layerId) {
return false;
}
+ for (int i = 0; i < 2; i++) {
+ ssize_t idx = mLayerReleaseFences[i].indexOfKey(layerId);
+ if (idx >= 0) {
+ HwcFenceControl::closeFd(mLayerReleaseFences[i].valueAt(idx));
+ mLayerReleaseFences[i].removeItemsAt(idx);
+ DTRACE("destroyLayer remove layer %lld from cur release list %p\n", layerId, &(mLayerReleaseFences[i]));
+ }
+ }
+
mHwcLayers.removeItem(layerId);
DEINIT_AND_DELETE_OBJ(layer);
return true;
@@ -201,9 +258,10 @@ int32_t PhysicalDevice::getClientTargetSupport(
uint32_t height,
int32_t /*android_pixel_format_t*/ format,
int32_t /*android_dataspace_t*/ dataspace) {
+ framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
- if (width == mFramebufferInfo->info.xres
- && height == mFramebufferInfo->info.yres
+ if (width == fbInfo->info.xres
+ && height == fbInfo->info.yres
&& format == HAL_PIXEL_FORMAT_RGBA_8888
&& dataspace == HAL_DATASPACE_UNKNOWN) {
return HWC2_ERROR_NONE;
@@ -211,8 +269,8 @@ int32_t PhysicalDevice::getClientTargetSupport(
DTRACE("fbinfo: [%d x %d], client: [%d x %d]"
"format: %d, dataspace: %d",
- mFramebufferInfo->info.xres,
- mFramebufferInfo->info.yres,
+ fbInfo->info.xres,
+ fbInfo->info.yres,
width, height, format, dataspace);
// TODO: ?
@@ -242,6 +300,7 @@ int32_t PhysicalDevice::getDisplayAttribute(
ETRACE("display %d is not connected.", mId);
}
+ // framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
DisplayConfig *configChosen = mDisplayConfigs.itemAt(config);
if (!configChosen) {
ETRACE("failed to get display config: %ld", config);
@@ -262,19 +321,19 @@ int32_t PhysicalDevice::getDisplayAttribute(
ETRACE("refresh period: %d", *outValue);
break;
case HWC2_ATTRIBUTE_WIDTH:
- //*outValue = mFramebufferInfo->info.xres;
+ //*outValue = fbInfo->info.xres;
*outValue = configChosen->getWidth();
break;
case HWC2_ATTRIBUTE_HEIGHT:
- //*outValue = mFramebufferInfo->info.yres;
+ //*outValue = fbInfo->info.yres;
*outValue = configChosen->getHeight();
break;
case HWC2_ATTRIBUTE_DPI_X:
- //*outValue = mFramebufferInfo->xdpi*1000;
+ //*outValue = fbInfo->xdpi*1000;
*outValue = configChosen->getDpiX() * 1000.0f;
break;
case HWC2_ATTRIBUTE_DPI_Y:
- //*outValue = mFramebufferInfo->ydpi*1000;
+ //*outValue = fbInfo->ydpi*1000;
*outValue = configChosen->getDpiY() * 1000.0f;
break;
default:
@@ -330,7 +389,11 @@ int32_t PhysicalDevice::getDisplayRequests(
HwcLayer *layer = mHwcLayersChangeRequest.valueAt(i);
if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE) {
// video overlay.
- if (layer->getBufferHandle()) {
+ if (layerId == mVideoOverlayLayerId) {
+ outLayers[i] = layerId;
+ outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
+ }
+ /* if (layer->getBufferHandle()) {
private_handle_t const* hnd =
reinterpret_cast<private_handle_t const*>(layer->getBufferHandle());
if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
@@ -338,7 +401,7 @@ int32_t PhysicalDevice::getDisplayRequests(
outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
continue;
}
- }
+ } */
}
// sideband stream.
@@ -412,72 +475,163 @@ int32_t PhysicalDevice::getHdrCapabilities(
return HWC2_ERROR_NONE;
}
+void PhysicalDevice::swapReleaseFence() {
+ //dumpFenceList(mHwcCurReleaseFences);
+
+ if (mHwcCurReleaseFences == NULL || mHwcPriorReleaseFences == NULL) {
+ if (mHwcCurReleaseFences) {
+ clearFenceList(mHwcPriorReleaseFences);
+ }
+
+ if (mHwcPriorReleaseFences) {
+ clearFenceList(mHwcPriorReleaseFences);
+ }
+
+ mHwcCurReleaseFences = &(mLayerReleaseFences[0]);
+ mHwcPriorReleaseFences = &(mLayerReleaseFences[1]);
+ } else {
+ KeyedVector<hwc2_layer_t, int32_t> * tmp = mHwcCurReleaseFences;
+ clearFenceList(mHwcPriorReleaseFences);
+ mHwcCurReleaseFences = mHwcPriorReleaseFences;
+ mHwcPriorReleaseFences = tmp;
+ }
+}
+
+
+void PhysicalDevice::addReleaseFence(hwc2_layer_t layerId, int32_t fenceFd) {
+ ssize_t idx = mHwcCurReleaseFences->indexOfKey(layerId);
+ if (idx >= 0 && idx < mHwcCurReleaseFences->size()) {
+ int32_t oldFence = mHwcCurReleaseFences->valueAt(idx);
+ String8 mergeName("hwc-release");
+ int32_t newFence = HwcFenceControl::merge(mergeName, oldFence, fenceFd);
+ mHwcCurReleaseFences->replaceValueAt(idx, newFence);
+ HwcFenceControl::closeFd(oldFence);
+ HwcFenceControl::closeFd(fenceFd);
+ ETRACE("addReleaseFence:(%d, %d) + %d -> (%d,%d)\n", idx, oldFence, fenceFd, idx, newFence);
+ dumpFenceList(mHwcCurReleaseFences);
+ } else {
+ mHwcCurReleaseFences->add(layerId, fenceFd);
+ }
+}
+
+void PhysicalDevice::clearFenceList(KeyedVector<hwc2_layer_t, int32_t> * fenceList) {
+ if (!fenceList || !fenceList->size())
+ return;
+
+ for (int i = 0; i < fenceList->size(); i++) {
+ int32_t fenceFd = fenceList->valueAt(i);
+ HwcFenceControl::closeFd(fenceFd);
+ DTRACE("clearFenceList close fd %d\n", fenceFd);
+ fenceList->replaceValueAt(i, -1);
+ }
+ fenceList->clear();
+}
+
+void PhysicalDevice::dumpFenceList(KeyedVector<hwc2_layer_t, int32_t> * fenceList) {
+ if (!fenceList || fenceList->isEmpty())
+ return;
+
+ String8 resultStr("dumpFenceList: ");
+ for (int i = 0; i < fenceList->size(); i++) {
+ hwc2_layer_t layerId = fenceList->keyAt(i);
+ int32_t fenceFd = fenceList->valueAt(i);
+ resultStr.appendFormat("(%lld, %d), ", layerId, fenceFd);
+ }
+
+ ETRACE("%s", resultStr.string());
+}
+
int32_t PhysicalDevice::getReleaseFences(
uint32_t* outNumElements,
hwc2_layer_t* outLayers,
int32_t* outFences) {
- HwcLayer* layer = NULL;
- uint32_t num_layer = 0;
+ *outNumElements = mHwcPriorReleaseFences->size();
- if (NULL == outLayers || NULL == outFences) {
- for (uint32_t i=0; i<mHwcLayers.size(); i++) {
- hwc2_layer_t layerId = mHwcLayers.keyAt(i);
- layer = mHwcLayers.valueAt(i);
- if (layer) num_layer++;
+ if (outLayers && outFences) {
+ for (uint32_t i=0; i<mHwcPriorReleaseFences->size(); i++) {
+ outLayers[i] = mHwcPriorReleaseFences->keyAt(i);
+ outFences[i] = HwcFenceControl::dupFence(mHwcPriorReleaseFences->valueAt(i));
}
- } else {
- for (uint32_t i=0; i<mHwcLayers.size(); i++) {
- hwc2_layer_t layerId = mHwcLayers.keyAt(i);
- layer = mHwcLayers.valueAt(i);
- if (layer) {
- DTRACE("outFences: %d", layer->getAcquireFence());
- /*if (layer->getAcquireFence() > -1) {
- close(layer->getAcquireFence());
- }*/
- if (layer->getAcquireFence() > -1) {
- outFences[num_layer] = layer->getAcquireFence();
- } else {
- outFences[num_layer] = -1;
- }
- outLayers[num_layer++] = layerId;
- layer->resetAcquireFence();
- // TODO: ?
- }
+ }
+
+ return HWC2_ERROR_NONE;
+}
+
+void PhysicalDevice::directCompose(framebuffer_info_t * fbInfo) {
+ HwcLayer* layer = NULL;
+ ssize_t idx = mHwcLayers.indexOfKey(mDirectRenderLayerId);
+ if (idx >= 0) {
+ layer = mHwcLayers.valueAt(idx);
+ if (mTargetAcquireFence > -1) {
+ ETRACE("ERROR:directCompose with mTargetAcquireFence %d\n", mTargetAcquireFence);
+ HwcFenceControl::closeFd(mTargetAcquireFence);
}
+
+ mTargetAcquireFence = layer->getDuppedAcquireFence();
+ mClientTargetHnd = layer->getBufferHandle();
+ DTRACE("Hit only one non video overlay layer, handle: %08" PRIxPTR ", fence: %d",
+ intptr_t(mClientTargetHnd), mTargetAcquireFence);
+
+ hwc_rect_t displayframe = layer->getDisplayFrame();
+ fbInfo->info.xoffset = displayframe.left;
+ fbInfo->info.yoffset = displayframe.top;
+ return;
}
- if (num_layer > 0) {
- DTRACE("There are %d layer requests.", num_layer);
- *outNumElements = num_layer;
- } else {
- DTRACE("No layer have set buffer yet.");
+ ETRACE("Didn't find direct compose layer!");
+}
+
+void PhysicalDevice::ge2dCompose(framebuffer_info_t * fbInfo, bool hasVideoOverlay) {
+ if (mGE2DRenderSortedLayerIds.size() > 0) {
+ DTRACE("GE2D compose mFbSlot: %d", mFbSlot);
+ if (hasVideoOverlay) {
+ if (mGE2DClearVideoRegionCount < 3) {
+ mComposer->setVideoOverlayLayerId(mVideoOverlayLayerId);
+ }
+ }
+ if (mTargetAcquireFence > -1) {
+ ETRACE("ERROR:GE2D compose with mTargetAcquireFence %d\n", mTargetAcquireFence);
+ HwcFenceControl::closeFd(mTargetAcquireFence);
+ }
+ mTargetAcquireFence = mComposer->startCompose(mGE2DRenderSortedLayerIds, &mFbSlot, mGE2DComposeFrameCount);
+ for (uint32_t i=0; i<mGE2DRenderSortedLayerIds.size(); i++) {
+ addReleaseFence(mGE2DRenderSortedLayerIds.itemAt(i), HwcFenceControl::dupFence(mTargetAcquireFence));
+ }
+ // HwcFenceControl::traceFenceInfo(mTargetAcquireFence);
+ // dumpLayers(mGE2DRenderSortedLayerIds);
+ if (mGE2DComposeFrameCount < 3) {
+ mGE2DComposeFrameCount++;
+ }
+ mClientTargetHnd = mComposer->getBufHnd();
+ fbInfo->yOffset = mFbSlot;
+ return;
}
- return HWC2_ERROR_NONE;
+ ETRACE("Didn't find ge2d compose layers!");
}
-int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence) {
+int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOverlay) {
HwcLayer* layer = NULL;
- int32_t err = 0;
void *cbuffer;
// deal physical display's client target layer
- framebuffer_info_t* cbinfo = mCursorContext->getCursorInfo();
+ framebuffer_info_t fbInfo = *(mFramebufferContext->getInfo());
+ framebuffer_info_t* cbInfo = mCursorContext->getInfo();
bool cursorShow = false;
for (uint32_t i=0; i<mHwcLayers.size(); i++) {
hwc2_layer_t layerId = mHwcLayers.keyAt(i);
layer = mHwcLayers.valueAt(i);
if (layer && layer->getCompositionType()== HWC2_COMPOSITION_CURSOR) {
- if (private_handle_t::validate(layer->getBufferHandle()) < 0) {
+ private_handle_t *hnd = (private_handle_t *)(layer->getBufferHandle());
+ if (private_handle_t::validate(hnd) < 0) {
ETRACE("invalid cursor layer handle.");
break;
}
- private_handle_t *hnd = (private_handle_t *)(layer->getBufferHandle());
DTRACE("This is a Sprite, hnd->stride is %d, hnd->height is %d", hnd->stride, hnd->height);
- if (cbinfo->info.xres != (uint32_t)hnd->stride || cbinfo->info.yres != (uint32_t)hnd->height) {
+ if (cbInfo->info.xres != (uint32_t)hnd->stride || cbInfo->info.yres != (uint32_t)hnd->height) {
ETRACE("disp: %d cursor need to redrew", mId);
- update_cursor_buffer_locked(cbinfo, hnd->stride, hnd->height);
- cbuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, cbinfo->fd, 0);
+ update_cursor_buffer_locked(cbInfo, hnd->stride, hnd->height);
+ cbuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, cbInfo->fd, 0);
if (cbuffer != MAP_FAILED) {
memcpy(cbuffer, hnd->base, hnd->size);
munmap(cbuffer, hnd->size);
@@ -491,68 +645,122 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence) {
}
}
+ if (mRenderMode == GLES_COMPOSE_MODE) {
+ /*private_handle_t const* buffer = reinterpret_cast<private_handle_t const*>(mClientTargetHnd);
+ if (buffer && private_handle_t::validate(buffer) == 0) {
+ uint32_t slot = buffer->offset / fbInfo.finfo.line_length;
+ mComposer->setCurGlesFbSlot(slot);
+ DTRACE("GLES compose Slot: %d", slot);
+ }*/
+ } else if (mRenderMode == DIRECT_COMPOSE_MODE) { // if only one layer exists, let hwc do her work.
+ directCompose(&fbInfo);
+ /* if (mGE2DComposeFrameCount != 0) {
+ addReleaseFence(mDirectRenderLayerId, HwcFenceControl::dupFence(mPriorFrameRetireFence));
+ }*/
+ } else if (mRenderMode == GE2D_COMPOSE_MODE) {
+ ge2dCompose(&fbInfo, hasVideoOverlay);
+ }
+ fbInfo.renderMode = mRenderMode;
+
+ if (hasVideoOverlay && mHwcLayers.size() == 1) {
+ fbInfo.op |= 0x00000001;
+ } else {
+ fbInfo.op &= ~0x00000001;
+ }
+
if (!mClientTargetHnd || private_handle_t::validate(mClientTargetHnd) < 0 || mPowerMode == HWC2_POWER_MODE_OFF) {
DTRACE("mClientTargetHnd is null or Enter suspend state, mTargetAcquireFence: %d", mTargetAcquireFence);
- if (mTargetAcquireFence > -1) {
- sync_wait(mTargetAcquireFence, 5000);
- close(mTargetAcquireFence);
- mTargetAcquireFence = -1;
- }
- *outRetireFence = -1;
+ *outRetireFence = HwcFenceControl::merge(String8("Layer"), mPriorFrameRetireFence, mTargetAcquireFence);
+ HwcFenceControl::closeFd(mTargetAcquireFence);
+ mTargetAcquireFence = -1;
+ HwcFenceControl::closeFd(mPriorFrameRetireFence);
+ mPriorFrameRetireFence = -1;
if (private_handle_t::validate(mClientTargetHnd) < 0) {
ETRACE("mClientTargetHnd is not validate!");
- return HWC2_ERROR_NONE;
}
- }
+ } else {
+ *outRetireFence = HwcFenceControl::dupFence(mPriorFrameRetireFence);
+ if (*outRetireFence >= 0) {
+ DTRACE("Get prior frame's retire fence %d", *outRetireFence);
+ } else {
+ ETRACE("No valid prior frame's retire returned. %d ", *outRetireFence);
+ // -1 means no fence, less than -1 is some error
+ *outRetireFence = -1;
+ }
+ HwcFenceControl::closeFd(mPriorFrameRetireFence);
+ mPriorFrameRetireFence = -1;
- *outRetireFence = mPriorFrameRetireFence;
+ // real post framebuffer here.
+ DTRACE("fbInfo->renderMode: %d", fbInfo.renderMode);
+ mPriorFrameRetireFence = fb_post_with_fence_locked(&fbInfo, mClientTargetHnd, mTargetAcquireFence);
+ mTargetAcquireFence = -1;
- if (*outRetireFence >= 0) {
- DTRACE("Get prior frame's retire fence %d", *outRetireFence);
- } else {
- ETRACE("No valid prior frame's retire returned. %d ", *outRetireFence);
- // -1 means no fence, less than -1 is some error
- *outRetireFence = -1;
- }
+ if (mRenderMode == GE2D_COMPOSE_MODE) {
+ mComposer->mergeRetireFence(mFbSlot, HwcFenceControl::dupFence(mPriorFrameRetireFence));
+ } else {
+ if (mGE2DComposeFrameCount != 0) {
+ mComposer->removeRetireFence(mFbSlot);
+ }
- mPriorFrameRetireFence = fb_post_with_fence_locked(mFramebufferInfo, mClientTargetHnd, mTargetAcquireFence);
- mTargetAcquireFence = -1;
+ if (mRenderMode == DIRECT_COMPOSE_MODE) {
+ addReleaseFence(mDirectRenderLayerId, HwcFenceControl::dupFence(mPriorFrameRetireFence));
+ }
+ }
- // finally we need to update cursor's blank status
- if (cbinfo->fd > 0 && cursorShow != mCursorContext->getCursorStatus()) {
- mCursorContext->setCursorStatus(cursorShow);
- DTRACE("UPDATE FB1 status to %d", !cursorShow);
- ioctl(cbinfo->fd, FBIOBLANK, !cursorShow);
+ // finally we need to update cursor's blank status.
+ if (cbInfo->fd > 0 && cursorShow != mCursorContext->getStatus()) {
+ mCursorContext->setStatus(cursorShow);
+ DTRACE("UPDATE FB1 status to %d", !cursorShow);
+ ioctl(cbInfo->fd, FBIOBLANK, !cursorShow);
+ }
}
- return err;
-}
+ if (mRenderMode != GE2D_COMPOSE_MODE) {
+ mGE2DComposeFrameCount = 0;
+ }
+ return HWC2_ERROR_NONE;
+}
int32_t PhysicalDevice::presentDisplay(
int32_t* outRetireFence) {
int32_t err = HWC2_ERROR_NONE;
HwcLayer* layer = NULL;
+ bool hasVideoOverlay = false;
if (mIsValidated) {
// TODO: need improve the way to set video axis.
#if WITH_LIBPLAYER_MODULE
- for (uint32_t i=0; i<mHwcLayers.size(); i++) {
- hwc2_layer_t layerId = mHwcLayers.keyAt(i);
- layer = mHwcLayers.valueAt(i);
-
- if (layer && layer->getCompositionType()== HWC2_COMPOSITION_DEVICE) {
+ ssize_t index = mHwcLayers.indexOfKey(mVideoOverlayLayerId);
+ if (index >= 0) {
+ layer = mHwcLayers.valueFor(mVideoOverlayLayerId);
+ if (layer != NULL) {
layer->presentOverlay();
- break;
+ hasVideoOverlay = true;
+ if (mGE2DClearVideoRegionCount < 3) {
+ mGE2DClearVideoRegionCount++;
+ }
}
+ } else {
+ mGE2DClearVideoRegionCount = 0;
}
#endif
- err = postFramebuffer(outRetireFence);
+ err = postFramebuffer(outRetireFence, hasVideoOverlay);
+
mIsValidated = false;
} else { // display not validate yet.
err = HWC2_ERROR_NOT_VALIDATED;
}
+ // reset layers' acquire fence.
+ for (uint32_t i=0; i<mHwcLayers.size(); i++) {
+ hwc2_layer_t layerId = mHwcLayers.keyAt(i);
+ layer = mHwcLayers.valueAt(i);
+ if (layer != NULL) {
+ layer->resetAcquireFence();
+ }
+ }
+
return err;
}
@@ -574,10 +782,8 @@ int32_t PhysicalDevice::setClientTarget(
if (NULL != target) {
mClientTargetHnd = target;
mClientTargetDamageRegion = damage;
- if (-1 != acquireFence) {
- mTargetAcquireFence = acquireFence;
- //sync_wait(mTargetAcquireFence, 3000);
- }
+ mTargetAcquireFence = acquireFence;
+ ETRACE("setClientTarget %p, %d", target, acquireFence);
// TODO: HWC2_ERROR_BAD_PARAMETER && dataspace && damage.
} else {
DTRACE("client target is null!, no need to update this frame.");
@@ -611,48 +817,272 @@ bool PhysicalDevice::vsyncControl(bool enabled) {
return mVsyncObserver->control(enabled);
}
+void PhysicalDevice::dumpLayers(Vector < hwc2_layer_t > layerIds) {
+ for (uint32_t x=0; x<layerIds.size(); x++) {
+ HwcLayer* layer = getLayerById(layerIds.itemAt(x));
+ static char const* compositionTypeName[] = {
+ "UNKNOWN",
+ "GLES",
+ "HWC",
+ "SOLID",
+ "HWC_CURSOR",
+ "SIDEBAND"};
+ ALOGE(" %11s | %12" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
+ compositionTypeName[layer->getCompositionType()],
+ intptr_t(layer->getBufferHandle()), layer->getZ(), layer->getDataspace(),
+ layer->getPlaneAlpha(), layer->getTransform(), layer->getBlendMode(),
+ layer->getSourceCrop().left, layer->getSourceCrop().top, layer->getSourceCrop().right, layer->getSourceCrop().bottom,
+ layer->getDisplayFrame().left, layer->getDisplayFrame().top, layer->getDisplayFrame().right, layer->getDisplayFrame().bottom);
+ }
+}
+
+void PhysicalDevice::dumpLayers(KeyedVector<hwc2_layer_t, HwcLayer*> layers) {
+ for (uint32_t x=0; x<layers.size(); x++) {
+ HwcLayer* layer = layers.valueAt(x);
+ static char const* compositionTypeName[] = {
+ "UNKNOWN",
+ "GLES",
+ "HWC",
+ "SOLID",
+ "HWC_CURSOR",
+ "SIDEBAND"};
+ ALOGE(" %11s | %12" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n",
+ compositionTypeName[layer->getCompositionType()],
+ intptr_t(layer->getBufferHandle()), layer->getZ(), layer->getDataspace(),
+ layer->getPlaneAlpha(), layer->getTransform(), layer->getBlendMode(),
+ layer->getSourceCrop().left, layer->getSourceCrop().top, layer->getSourceCrop().right, layer->getSourceCrop().bottom,
+ layer->getDisplayFrame().left, layer->getDisplayFrame().top, layer->getDisplayFrame().right, layer->getDisplayFrame().bottom);
+ }
+}
+
+bool PhysicalDevice::layersStateCheck(int32_t renderMode,
+ KeyedVector<hwc2_layer_t, HwcLayer*> & composeLayers) {
+ bool ret = false;
+ uint32_t layerNum = composeLayers.size();
+ hwc_frect_t sourceCrop[GE2D_COMPOSE_MAX_LAYERS];
+ HwcLayer* layer[GE2D_COMPOSE_MAX_LAYERS] = { NULL, NULL, NULL };
+ private_handle_t const* hnd[GE2D_COMPOSE_MAX_LAYERS] = { NULL, NULL, NULL };
+ hwc_rect_t displayFrame[GE2D_COMPOSE_MAX_LAYERS];
+
+ for (int32_t i=0; i<layerNum; i++) {
+ layer[i] = composeLayers.valueAt(i);
+ sourceCrop[i] = layer[i]->getSourceCrop();
+ displayFrame[i] = layer[i]->getDisplayFrame();
+ hnd[i] = reinterpret_cast<private_handle_t const*>(layer[i]->getBufferHandle());
+ ALOGD("layer[%d] zorder: %d, blend: %d, PlaneAlpha: %f, "
+ "mColor: [%d, %d, %d, %d], mDataSpace: %d, format hnd[%d]: %x",
+ i, layer[i]->getZ(), layer[i]->getBlendMode(), layer[i]->getPlaneAlpha(),
+ layer[i]->getColor().r, layer[i]->getColor().g, layer[i]->getColor().b,
+ layer[i]->getColor().a, layer[i]->getDataspace(), i, hnd[i]->format);
+ }
+
+ if (renderMode == DIRECT_COMPOSE_MODE) {
+ switch (hnd[0]->format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGB_888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ ALOGD("Layer format match direct composer.");
+ ret = true;
+ break;
+ default:
+ ALOGD("Layer format not support by direct compose");
+ return false;
+ break;
+ }
+ if (layer[0]->isCropped()
+ || layer[0]->isScaled()
+ || layer[0]->isOffset()) {
+ ALOGD("direct compose can not process!");
+ return false;
+ }
+ }else if (renderMode == GE2D_COMPOSE_MODE) {
+ bool yuv420Sp = false;
+ for (int32_t i=0; i<layerNum; i++) {
+ switch (hnd[i]->format) {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ yuv420Sp = true;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGB_888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_Y8:
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ ALOGD("Layer format match ge2d composer.");
+ ret = true;
+ break;
+ default:
+ ALOGD("Layer format not support by ge2d");
+ return false;
+ break;
+ }
+ if (layer[i]->havePlaneAlpha()
+ || layer[i]->haveColor()
+ || layer[i]->haveDataspace()
+ || (layer[i]->isBlended()
+ && layer[i]->isScaled())) {
+ ALOGD("ge2d compose can not process!");
+ return false;
+ }
+ }
+
+ if (yuv420Sp && GE2D_COMPOSE_TWO_LAYERS == layerNum) {
+ if (Utils::compareRect(sourceCrop[0], sourceCrop[1])
+ && Utils::compareRect(sourceCrop[0], displayFrame[0])
+ && Utils::compareRect(sourceCrop[1], displayFrame[1])) {
+ ALOGD("2 layers is same size and have yuv420sp format ge2d compose can not process!");
+ return false;
+ }
+
+ }
+ }
+
+ return ret;
+}
+
+/*************************************************************
+ * For direct framebuffer composer:
+ * 1) only support one layer.
+ * 2) layer format: rgba, rgbx,rgb565,bgra;
+ * 3) layer no need scale to display;
+ * 4) layer has no offset to display; (will support later.)
+
+ * For ge2d composer:
+ * 1) support layer format that direct composer can't support.
+ * 2) support 2 layers blending.
+ * 3) support scale and rotation etc.
+**************************************************************/
+int32_t PhysicalDevice::composersFilter(
+ KeyedVector<hwc2_layer_t, HwcLayer*> & composeLayers) {
+
+ // direct Composer.
+ if (composeLayers.size() == GE2D_COMPOSE_ONE_LAYER) {
+ // if only one layer exists, do direct framebuffer composer.
+ bool directCompose = layersStateCheck(DIRECT_COMPOSE_MODE, composeLayers);
+ if (directCompose) {
+ hwc2_layer_t layerGlesLayerId = composeLayers.keyAt(0);
+ composeLayers.clear();
+ mDirectRenderLayerId = layerGlesLayerId;
+ return DIRECT_COMPOSE_MODE;
+ }
+ }
+
+ // if direct composer can't work, try this.
+ if (composeLayers.size() > GE2D_COMPOSE_NO_LAYER
+ && composeLayers.size() < GE2D_COMPOSE_MAX_LAYERS) {
+ bool ge2dCompose = layersStateCheck(GE2D_COMPOSE_MODE, composeLayers);
+ if (!ge2dCompose) return GLES_COMPOSE_MODE;
+ mGE2DRenderSortedLayerIds.clear();
+ for (uint32_t i=0; i<composeLayers.size(); i++) {
+ hwc2_layer_t layerGlesLayerId = composeLayers.keyAt(i);
+ HwcLayer* layer = getLayerById(layerGlesLayerId);
+ if (0 == i) {
+ mGE2DRenderSortedLayerIds.push_front(layerGlesLayerId);
+ continue;
+ }
+ for (uint32_t j=0; j<i; j++) {
+ HwcLayer* layer1 = getLayerById(mGE2DRenderSortedLayerIds.itemAt(j));
+ HwcLayer* layer2 = getLayerById(layerGlesLayerId);
+ if (layer1 != NULL && layer2 != NULL) {
+ uint32_t z1 = layer1->getZ();
+ uint32_t z2 = layer2->getZ();
+ if (layer1->getZ() > layer2->getZ()) {
+ mGE2DRenderSortedLayerIds.insertAt(layerGlesLayerId, j, 1);
+ break;
+ }
+ if (j == i-1) mGE2DRenderSortedLayerIds.push_back(layerGlesLayerId);
+ } else {
+ ETRACE("Layer1 or Layer2 is NULL!!!");
+ }
+ }
+ }
+
+ // Vector < hwc2_layer_t > layerIds;
+ if (!mComposer) {
+ // create ge2d composer...
+ mComposer = mControlFactory->createComposer(*this);
+ if (!mComposer || !mComposer->initialize(mFramebufferContext->getInfo())) {
+ DEINIT_AND_DELETE_OBJ(mComposer);
+ return GLES_COMPOSE_MODE;
+ }
+ }
+ composeLayers.clear();
+ return GE2D_COMPOSE_MODE;
+ }
+
+ return GLES_COMPOSE_MODE;
+}
+
+void PhysicalDevice::clearFramebuffer() {
+ hwc_rect_t clipRect;
+ framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
+ uint32_t addr = getIonPhyAddr(fbInfo, mFramebufferHnd);
+ clipRect.left = 0;
+ clipRect.top = 0;
+ clipRect.right = fbInfo->info.xres;
+ clipRect.bottom = fbInfo->info.yres_virtual;
+ mComposer->fillRectangle(clipRect, 0, addr);
+
+ DTRACE("Composer mode: %d, %d layers", mRenderMode, mHwcLayers.size());
+}
+
int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
uint32_t* outNumRequests) {
HwcLayer* layer = NULL;
bool istvp = false;
+ bool glesCompose = false;
+ bool isContinuousBuf = true;
+
+ mRenderMode = GLES_COMPOSE_MODE;
+ mVideoOverlayLayerId = 0;
+ swapReleaseFence();
for (uint32_t i=0; i<mHwcLayers.size(); i++) {
hwc2_layer_t layerId = mHwcLayers.keyAt(i);
layer = mHwcLayers.valueAt(i);
- if (layer) {
+ if (layer != NULL) {
// Physical Display.
- if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE) {
- // video overlay.
- if (layer->getBufferHandle()) {
- private_handle_t const* hnd =
- reinterpret_cast<private_handle_t const*>(layer->getBufferHandle());
+ private_handle_t const* hnd =
+ reinterpret_cast<private_handle_t const*>(layer->getBufferHandle());
+ if (hnd) {
+ if (!(hnd->flags & private_handle_t::PRIV_FLAGS_CONTINUOUS_BUF)) {
+ ALOGE("continous buffer flag is not set!");
+ isContinuousBuf = false;
+ }
+ if (hnd && layer->getCompositionType() == HWC2_COMPOSITION_DEVICE) {
+ // video overlay.
if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OMX) {
set_omx_pts((char*)hnd->base, &Amvideo_Handle);
istvp = true;
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
+ ETRACE("PRIV_FLAGS_VIDEO_OVERLAY!!!!");
+ mVideoOverlayLayerId = layerId;
mHwcLayersChangeRequest.add(layerId, layer);
continue;
}
- }
- // change all other device type to client.
- mHwcLayersChangeType.add(layerId, layer);
- continue;
+ mHwcGlesLayers.add(layerId, layer);
+ continue;
+ }
}
// cursor layer.
if (layer->getCompositionType() == HWC2_COMPOSITION_CURSOR) {
- DTRACE("This is a Cursor layer!");
+ ETRACE("This is a Cursor layer!");
mHwcLayersChangeRequest.add(layerId, layer);
continue;
}
// sideband stream.
if (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND
- && layer->getSidebandStream()) {
+ && layer->getSidebandStream()) {
// TODO: we just transact SIDEBAND to OVERLAY for now;
- DTRACE("get HWC_SIDEBAND layer, just change to overlay");
+ ETRACE("get HWC_SIDEBAND layer, just change to overlay");
mHwcLayersChangeRequest.add(layerId, layer);
mHwcLayersChangeType.add(layerId, layer);
continue;
@@ -660,28 +1090,57 @@ int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
// TODO: solid color.
if (layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
- DTRACE("This is a Solid Color layer!");
- //mHwcLayersChangeRequest.add(layerId, layer);
- mHwcLayersChangeType.add(layerId, layer);
+ ETRACE("This is a Solid Color layer!");
+ // mHwcLayersChangeRequest.add(layerId, layer);
+ // mHwcLayersChangeType.add(layerId, layer);
+ mHwcGlesLayers.add(layerId, layer);
continue;
}
+
+ if (layer->getCompositionType() == HWC2_COMPOSITION_CLIENT) {
+ ETRACE("Meet a client layer!");
+ glesCompose = true;
+ }
}
}
+ bool noDevComp = Utils::checkBoolProp("sys.sf.debug.nohwc");
+#ifndef USE_CONTINOUS_BUFFER_COMPOSER
+ ALOGE("No continous buffer composer!");
+ noDevComp = true;
+#endif
+
+ // dumpLayers(mHwcLayers);
+ if (isContinuousBuf && !glesCompose && !noDevComp) {
+ mRenderMode = composersFilter(mHwcGlesLayers);
+ }
+
+ if (mHwcLayers.size() == 0 && mComposer) {
+ clearFramebuffer();
+ }
+
+ if (mHwcGlesLayers.size() > 0) {
+ for (int i=0;i<mHwcGlesLayers.size(); i++) {
+ mHwcLayersChangeType.add(mHwcGlesLayers.keyAt(i), mHwcGlesLayers.valueAt(i));
+ }
+ mHwcGlesLayers.clear();
+ }
+
if (istvp == false && Amvideo_Handle!=0) {
closeamvideo();
Amvideo_Handle = 0;
}
if (mHwcLayersChangeRequest.size() > 0) {
- DTRACE("There are %d layer requests.", mHwcLayersChangeRequest.size());
+ ETRACE("There are %d layer requests.", mHwcLayersChangeRequest.size());
*outNumRequests = mHwcLayersChangeRequest.size();
}
// mark the validate function is called.(???)
mIsValidated = true;
+
if (mHwcLayersChangeType.size() > 0) {
- DTRACE("there are %d layer types has changed.", mHwcLayersChangeType.size());
+ ETRACE("there are %d layer types has changed.", mHwcLayersChangeType.size());
*outNumTypes = mHwcLayersChangeType.size();
return HWC2_ERROR_HAS_CHANGES;
}
@@ -692,15 +1151,15 @@ int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
int32_t PhysicalDevice::setCursorPosition(hwc2_layer_t layerId, int32_t x, int32_t y) {
HwcLayer* layer = getLayerById(layerId);
if (layer && HWC2_COMPOSITION_CURSOR == layer->getCompositionType()) {
- framebuffer_info_t* cbinfo = mCursorContext->getCursorInfo();
+ framebuffer_info_t* cbInfo = mCursorContext->getInfo();
fb_cursor cinfo;
- if (cbinfo->fd < 0) {
- ETRACE("setCursorPosition fd=%d", cbinfo->fd );
+ if (cbInfo->fd < 0) {
+ ETRACE("setCursorPosition fd=%d", cbInfo->fd );
}else {
cinfo.hot.x = x;
cinfo.hot.y = y;
DTRACE("setCursorPosition x_pos=%d, y_pos=%d", cinfo.hot.x, cinfo.hot.y);
- ioctl(cbinfo->fd, FBIO_CURSOR, &cinfo);
+ ioctl(cbInfo->fd, FBIO_CURSOR, &cinfo);
}
} else {
ETRACE("setCursorPosition bad layer.");
@@ -720,62 +1179,65 @@ int32_t PhysicalDevice::initDisplay() {
Mutex::Autolock _l(mLock);
if (!mFramebufferHnd) {
- mFramebufferInfo = new framebuffer_info_t();
- //init information from osd.
- mFramebufferInfo->displayType = mId;
- mFramebufferInfo->fbIdx = getOsdIdx(mId);
- int32_t err = init_frame_buffer_locked(mFramebufferInfo);
- int32_t bufferSize = mFramebufferInfo->finfo.line_length
- * mFramebufferInfo->info.yres;
+ // init framebuffer context.
+ mFramebufferContext = new FBContext();
+ framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
+ // init information from osd.
+ fbInfo->displayType = mId;
+ fbInfo->fbIdx = getOsdIdx(mId);
+ int32_t err = init_frame_buffer_locked(fbInfo);
+ int32_t bufferSize = fbInfo->finfo.line_length
+ * fbInfo->info.yres;
DTRACE("init_frame_buffer get fbinfo->fbIdx (%d) "
"fbinfo->info.xres (%d) fbinfo->info.yres (%d)",
- mFramebufferInfo->fbIdx, mFramebufferInfo->info.xres,
- mFramebufferInfo->info.yres);
+ fbInfo->fbIdx, fbInfo->info.xres,
+ fbInfo->info.yres);
int32_t usage = 0;
private_module_t *grallocModule = Hwcomposer::getInstance().getGrallocModule();
if (mId == HWC_DISPLAY_PRIMARY) {
- grallocModule->fb_primary.fb_info = *(mFramebufferInfo);
+ grallocModule->fb_primary.fb_info = *(fbInfo);
} else if (mId == HWC_DISPLAY_EXTERNAL) {
- grallocModule->fb_external.fb_info = *(mFramebufferInfo);
+ grallocModule->fb_external.fb_info = *(fbInfo);
usage |= GRALLOC_USAGE_EXTERNAL_DISP;
}
+ fbInfo->grallocModule = grallocModule;
//Register the framebuffer to gralloc module
mFramebufferHnd = new private_handle_t(
private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
- usage, mFramebufferInfo->fbSize, 0,
- 0, mFramebufferInfo->fd, bufferSize, 0);
+ usage, fbInfo->fbSize, 0,
+ 0, fbInfo->fd, bufferSize, 0);
grallocModule->base.registerBuffer(&(grallocModule->base), mFramebufferHnd);
DTRACE("init_frame_buffer get frame size %d usage %d",
- bufferSize,usage);
+ bufferSize, usage);
}
mIsConnected = true;
// init cursor framebuffer
- mCursorContext = new CursorContext();
- framebuffer_info_t* cbinfo = mCursorContext->getCursorInfo();
- cbinfo->fd = -1;
+ mCursorContext = new FBContext();
+ framebuffer_info_t* cbInfo = mCursorContext->getInfo();
+ cbInfo->fd = -1;
//init information from cursor framebuffer.
- cbinfo->fbIdx = mId*2+1;
- if (1 != cbinfo->fbIdx && 3 != cbinfo->fbIdx) {
+ cbInfo->fbIdx = mId*2+1;
+ if (1 != cbInfo->fbIdx && 3 != cbInfo->fbIdx) {
ETRACE("invalid fb index: %d, need to check!",
- cbinfo->fbIdx);
+ cbInfo->fbIdx);
return 0;
}
- int32_t err = init_cursor_buffer_locked(cbinfo);
+ int32_t err = init_cursor_buffer_locked(cbInfo);
if (err != 0) {
ETRACE("init_cursor_buffer_locked failed, need to check!");
return 0;
}
ITRACE("init_cursor_buffer get cbinfo->fbIdx (%d) "
"cbinfo->info.xres (%d) cbinfo->info.yres (%d)",
- cbinfo->fbIdx,
- cbinfo->info.xres,
- cbinfo->info.yres);
+ cbInfo->fbIdx,
+ cbInfo->info.xres,
+ cbInfo->info.yres);
- if ( cbinfo->fd >= 0) {
+ if ( cbInfo->fd >= 0) {
DTRACE("init_cursor_buffer success!");
}else{
DTRACE("init_cursor_buffer fail!");
@@ -813,7 +1275,8 @@ bool PhysicalDevice::updateDisplayConfigs()
}
ETRACE("output mode refresh rate: %d", rate);
- ret |= Utils::checkVinfo(mFramebufferInfo);
+ framebuffer_info_t* fbinfo = mFramebufferContext->getInfo();
+ ret |= Utils::checkVinfo(fbinfo);
if (ret) {
// reset display configs
@@ -823,10 +1286,10 @@ bool PhysicalDevice::updateDisplayConfigs()
// use active fb dimension as config width/height
DisplayConfig *config = new DisplayConfig(rate,
- mFramebufferInfo->info.xres,
- mFramebufferInfo->info.yres,
- mFramebufferInfo->xdpi,
- mFramebufferInfo->ydpi);
+ fbinfo->info.xres,
+ fbinfo->info.yres,
+ fbinfo->xdpi,
+ fbinfo->ydpi);
// add it to the front of other configs
mDisplayConfigs.push_front(config);
@@ -980,7 +1443,7 @@ exit:
void PhysicalDevice::dump(Dump& d) {
Mutex::Autolock _l(mLock);
d.append("-------------------------------------------------------------"
- "------------------------------------------------------------\n");
+ "----------------------------------------------------------------\n");
d.append("Device Name: %s (%s)\n", mName,
mIsConnected ? "connected" : "disconnected");
d.append(" CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |"
@@ -1005,14 +1468,14 @@ void PhysicalDevice::dump(Dump& d) {
// dump layer list
d.append(" Layers state:\n");
d.append(" numLayers=%zu\n", mHwcLayers.size());
- d.append(" numChangedTypeLayers=%zu\n", mHwcLayersChangeType.size());
- d.append(" numChangedRequestLayers=%zu\n", mHwcLayersChangeRequest.size());
+ // d.append(" numChangedTypeLayers=%zu\n", mHwcLayersChangeType.size());
+ // d.append(" numChangedRequestLayers=%zu\n", mHwcLayersChangeRequest.size());
if (mHwcLayers.size() > 0) {
d.append(
- " type | handle | zorder | ds | alpa | tr | blnd |"
+ " type | handle | zorder | ds | alpa | tr | blnd |"
" source crop (l,t,r,b) | frame \n"
- " -------------+----------+------------+----+------+----+------+"
+ " -------------+--------------+------------+----+------+----+------+"
"--------------------------------+------------------------\n");
for (uint32_t i=0; i<mHwcLayers.size(); i++) {
hwc2_layer_t layerId = mHwcLayers.keyAt(i);
diff --git a/hwc2/common/devices/PrimaryDevice.cpp b/hwc2/common/devices/PrimaryDevice.cpp
index 8f5b434..f49ebae 100644
--- a/hwc2/common/devices/PrimaryDevice.cpp
+++ b/hwc2/common/devices/PrimaryDevice.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <HwcTrace.h>
@@ -10,8 +22,8 @@
namespace android {
namespace amlogic {
-PrimaryDevice::PrimaryDevice(Hwcomposer& hwc)
- : PhysicalDevice(DEVICE_PRIMARY, hwc)
+PrimaryDevice::PrimaryDevice(Hwcomposer& hwc, DeviceControlFactory* controlFactory)
+ : PhysicalDevice(DEVICE_PRIMARY, hwc, controlFactory)
{
CTRACE();
}
diff --git a/hwc2/common/devices/VirtualDevice.cpp b/hwc2/common/devices/VirtualDevice.cpp
index c298b5e..478b500 100644
--- a/hwc2/common/devices/VirtualDevice.cpp
+++ b/hwc2/common/devices/VirtualDevice.cpp
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#include <HwcTrace.h>
#include <Hwcomposer.h>
#include <VirtualDevice.h>
@@ -499,7 +512,7 @@ int32_t VirtualDevice::setOutputBuffer(
void VirtualDevice::dump(Dump& d) {
Mutex::Autolock _l(mLock);
d.append("----------------------------------------------------------"
- "---------------------------------------------------------------\n");
+ "-------------------------------------------------------------------\n");
d.append("Device Name: %s (%s)\n", mName,
mIsConnected ? "connected" : "disconnected");
@@ -509,9 +522,9 @@ void VirtualDevice::dump(Dump& d) {
d.append(" numChangedTypeLayers=%zu\n", mHwcLayersChangeType.size());
if (mHwcLayers.size() > 0) {
d.append(
- " type | handle | zorder | ds | alpa | tr | blnd |"
+ " type | handle | zorder | ds | alpa | tr | blnd |"
" source crop (l,t,r,b) | frame \n"
- " -------------+----------+------------+----+------+----+------+"
+ " -------------+--------------+------------+----+------+----+------+"
"--------------------------------+------------------------\n");
for (uint32_t i=0; i<mHwcLayers.size(); i++) {
hwc2_layer_t layerId = mHwcLayers.keyAt(i);
diff --git a/hwc2/common/observers/SoftVsyncObserver.cpp b/hwc2/common/observers/SoftVsyncObserver.cpp
index 44cda76..7fc3ecb 100644
--- a/hwc2/common/observers/SoftVsyncObserver.cpp
+++ b/hwc2/common/observers/SoftVsyncObserver.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <HwcTrace.h>
diff --git a/hwc2/common/observers/SoftVsyncObserver.h b/hwc2/common/observers/SoftVsyncObserver.h
index 027e8e3..6cf1c2b 100644
--- a/hwc2/common/observers/SoftVsyncObserver.h
+++ b/hwc2/common/observers/SoftVsyncObserver.h
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#ifndef SOFT_VSYNC_OBSERVER_H
diff --git a/hwc2/common/observers/UeventObserver.cpp b/hwc2/common/observers/UeventObserver.cpp
index ea64c86..7d9d3c5 100644
--- a/hwc2/common/observers/UeventObserver.cpp
+++ b/hwc2/common/observers/UeventObserver.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <poll.h>
diff --git a/hwc2/common/utils/Dump.cpp b/hwc2/common/utils/Dump.cpp
index e9809bd..da06f38 100644
--- a/hwc2/common/utils/Dump.cpp
+++ b/hwc2/common/utils/Dump.cpp
@@ -1,5 +1,17 @@
/*
-// Copyright (c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#include <stdarg.h>
diff --git a/hwc2/common/utils/Dump.h b/hwc2/common/utils/Dump.h
index 7f97317..ea4fce5 100644
--- a/hwc2/common/utils/Dump.h
+++ b/hwc2/common/utils/Dump.h
@@ -1,6 +1,19 @@
/*
-// Copyright (c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef DUMP_H_
#define DUMP_H_
diff --git a/hwc2/common/utils/HwcTrace.h b/hwc2/common/utils/HwcTrace.h
index 6041cf2..7b913cb 100644
--- a/hwc2/common/utils/HwcTrace.h
+++ b/hwc2/common/utils/HwcTrace.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef HWC_TRACE_H
#define HWC_TRACE_H
@@ -13,8 +26,8 @@
extern "C" {
#endif
-//#define DEBUG
-#ifdef DEBUG
+// #define HWC_DEBUG
+#ifdef HWC_DEBUG
// Helper to automatically preappend classname::functionname to the log message
#define VTRACE(fmt,...) ALOGV("%s: " fmt, __func__, ##__VA_ARGS__)
#define DTRACE(fmt,...) ALOGD("%s: " fmt, __func__, ##__VA_ARGS__)
diff --git a/hwc2/common/utils/Utils.cpp b/hwc2/common/utils/Utils.cpp
index 9af81fc..9104e17 100644
--- a/hwc2/common/utils/Utils.cpp
+++ b/hwc2/common/utils/Utils.cpp
@@ -49,18 +49,18 @@ int32_t Utils::checkIntProp(const char* prop) {
return 0;
}
-int32_t Utils::checkAndDupFence(int32_t fence) {
- if (fence < 0) {
- ETRACE("not a vliad fence %d",fence);
+int32_t Utils::checkAndDupFd(int32_t fd) {
+ if (fd < 0) {
+ ETRACE("not a vliad fd %d", fd);
return -1;
}
- int32_t dup_fence = dup(fence);
- if (dup_fence < 0) {
- ETRACE("fence dup failed: %s", strerror(errno));
+ int32_t dup_fd = ::dup(fd);
+ if (dup_fd < 0) {
+ ETRACE("fd dup failed: %s", strerror(errno));
}
- return dup_fence;
+ return dup_fd;
}
#if WITH_LIBPLAYER_MODULE
@@ -117,32 +117,32 @@ bool Utils::checkOutputMode(char* curmode, int32_t* rate) {
return true;
}
-bool Utils::checkVinfo(framebuffer_info_t *fbinfo) {
- if (fbinfo != NULL && fbinfo->fd >= 0) {
+bool Utils::checkVinfo(framebuffer_info_t *fbInfo) {
+ if (fbInfo != NULL && fbInfo->fd >= 0) {
struct fb_var_screeninfo vinfo;
- if (ioctl(fbinfo->fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
+ if (ioctl(fbInfo->fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
{
ALOGE("FBIOGET_VSCREENINFO error!!!");
return -errno;
}
- if (vinfo.xres != fbinfo->info.xres
- || vinfo.yres != fbinfo->info.yres
- || vinfo.width != fbinfo->info.width
- || vinfo.height != fbinfo->info.height) {
+ if (vinfo.xres != fbInfo->info.xres
+ || vinfo.yres != fbInfo->info.yres
+ || vinfo.width != fbInfo->info.width
+ || vinfo.height != fbInfo->info.height) {
if (int32_t(vinfo.width) <= 16 || int32_t(vinfo.height) <= 9) {
// the driver doesn't return that information
// default to 160 dpi
vinfo.width = ((vinfo.xres * 25.4f)/160.0f + 0.5f);
vinfo.height = ((vinfo.yres * 25.4f)/160.0f + 0.5f);
}
- fbinfo->xdpi = (vinfo.xres * 25.4f) / vinfo.width;
- fbinfo->ydpi = (vinfo.yres * 25.4f) / vinfo.height;
+ fbInfo->xdpi = (vinfo.xres * 25.4f) / vinfo.width;
+ fbInfo->ydpi = (vinfo.yres * 25.4f) / vinfo.height;
- fbinfo->info.xres = vinfo.xres;
- fbinfo->info.yres = vinfo.yres;
- fbinfo->info.width = vinfo.width;
- fbinfo->info.height = vinfo.height;
+ fbInfo->info.xres = vinfo.xres;
+ fbInfo->info.yres = vinfo.yres;
+ fbInfo->info.width = vinfo.width;
+ fbInfo->info.height = vinfo.height;
return true;
}
diff --git a/hwc2/common/utils/Utils.h b/hwc2/common/utils/Utils.h
index a6783a6..351fb22 100644
--- a/hwc2/common/utils/Utils.h
+++ b/hwc2/common/utils/Utils.h
@@ -27,7 +27,10 @@ public:
~Utils();
static bool checkBoolProp(const char* prop);
static int32_t checkIntProp(const char* prop);
- static int32_t checkAndDupFence(int32_t fence);
+ static int32_t checkAndDupFd(int32_t fd);
+ static inline void closeFd(int32_t fd) {
+ if (fd > -1) close(fd);
+ }
#if WITH_LIBPLAYER_MODULE
static bool checkSysfsStatus(const char* sysfstr, char* lastr, int32_t size);
#endif
@@ -39,6 +42,39 @@ public:
static const char* getHotplugInString();
static const char* getHotplugOutString();
+ template <typename T, typename S>
+ static inline bool compareRect(T a, S b) {
+ if ((int32_t)a.left == (int32_t)b.left
+ && (int32_t)a.top == (int32_t)b.top
+ && (int32_t)a.right == (int32_t)b.right
+ && (int32_t)a.bottom == (int32_t)b.bottom) {
+ return true;
+ }
+ return false;
+ }
+ template <typename T, typename S>
+ static inline bool compareSize(T a, S b) {
+ if ((int32_t)(a.right-a.left) == (int32_t)(b.right-b.left)
+ && (int32_t)(a.bottom-a.top) == (int32_t)(b.bottom-b.top)) {
+ return true;
+ }
+ return false;
+ }
+ template <typename T>
+ static inline T min(T a, T b) {
+ return a<b ? a : b;
+ }
+ template <typename T>
+ static inline T max(T a, T b) {
+ return a>b ? a : b;
+ }
+ template <typename T>
+ static inline void swap(T& a, T& b) {
+ T t = a;
+ a = b;
+ b = t;
+ }
+
};
} // namespace amlogic
diff --git a/hwc2/include/ExternalDevice.h b/hwc2/include/ExternalDevice.h
index 346005b..f743690 100644
--- a/hwc2/include/ExternalDevice.h
+++ b/hwc2/include/ExternalDevice.h
@@ -1,6 +1,19 @@
/*
-// Copyright (c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef EXTERNAL_DEVICE_H
#define EXTERNAL_DEVICE_H
diff --git a/hwc2/include/HwcFenceControl.h b/hwc2/include/HwcFenceControl.h
new file mode 100644
index 0000000..ed0e380
--- a/dev/null
+++ b/hwc2/include/HwcFenceControl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HWC_FENCE_H
+#define HWC_FENCE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/String8.h>
+#include <utils/Timers.h>
+#include <utils/StrongPointer.h>
+#include <utils/RefBase.h>
+
+
+namespace android {
+namespace amlogic {
+
+
+// ===========================================================================
+// HwcFenceControl
+// ===========================================================================
+
+class HwcFenceControl
+ : public LightRefBase<HwcFenceControl>
+{
+public:
+ static const sp<HwcFenceControl> NO_FENCE;
+
+ // TIMEOUT_NEVER may be passed to the wait method to indicate that it
+ // should wait indefinitely for the fence to signal.
+ enum { TIMEOUT_NEVER = -1 };
+
+ // Construct a new Fence object with an invalid file descriptor. This
+ // should be done when the Fence object will be set up by unflattening
+ // serialized data.
+ HwcFenceControl();
+
+ // Construct a new Fence object to manage a given fence file descriptor.
+ // When the new Fence object is destructed the file descriptor will be
+ // closed.
+ HwcFenceControl(int32_t fenceFd);
+
+ // Check whether the Fence has an open fence file descriptor. Most Fence
+ // methods treat an invalid file descriptor just like a valid fence that
+ // is already signalled, so using this is usually not necessary.
+ bool isValid() const { return mFenceFd != -1; }
+
+ // wait waits for up to timeout milliseconds for the fence to signal. If
+ // the fence signals then NO_ERROR is returned. If the timeout expires
+ // before the fence signals then -ETIME is returned. A timeout of
+ // TIMEOUT_NEVER may be used to indicate that the call should wait
+ // indefinitely for the fence to signal.
+ static status_t wait(int32_t fence, int32_t timeout);
+
+ // waitForever is a convenience function for waiting forever for a fence to
+ // signal (just like wait(TIMEOUT_NEVER)), but issuing an error to the
+ // system log and fence state to the kernel log if the wait lasts longer
+ // than a warning timeout.
+ // The logname argument should be a string identifying
+ // the caller and will be included in the log message.
+ status_t waitForever(const char* logname);
+
+ // fence.
+ static int32_t createFenceTimeline();
+ static int32_t createFence(int32_t syncTimelineFd,char* str, uint32_t val);
+ static status_t syncTimelineInc(int32_t syncTimelineFd);
+ static status_t traceFenceInfo(int32_t fence);
+
+ static inline void closeFd(int32_t fence) {
+ if (fence > -1) {
+ close(fence);
+ }
+ }
+ static inline void waitAndCloseFd(int32_t fence, int32_t timeout) {
+ if (fence > -1) {
+ wait(fence, timeout);
+ close(fence);
+ }
+ }
+
+ // merge combines two Fence objects, creating a new Fence object that
+ // becomes signaled when both f1 and f2 are signaled (even if f1 or f2 is
+ // destroyed before it becomes signaled). The name argument specifies the
+ // human-readable name to associated with the new Fence object.
+ static int32_t merge(const String8& name, const int32_t& f1,
+ const int32_t& f2);
+
+ // Return a duplicate of the fence file descriptor. The caller is
+ // responsible for closing the returned file descriptor. On error, -1 will
+ // be returned and errno will indicate the problem.
+ int32_t dup() const;
+ static int32_t dupFence(int32_t fence);
+
+ int32_t getFenceFd() const;
+
+ // getSignalTime returns the system monotonic clock time at which the
+ // fence transitioned to the signaled state. If the fence is not signaled
+ // then INT64_MAX is returned. If the fence is invalid or if an error
+ // occurs then -1 is returned.
+ nsecs_t getSignalTime() const;
+
+private:
+ // Only allow instantiation using ref counting.
+ friend class LightRefBase<HwcFenceControl>;
+ ~HwcFenceControl();
+
+ // Disallow copying
+ HwcFenceControl(const HwcFenceControl& rhs);
+ HwcFenceControl& operator = (const HwcFenceControl& rhs);
+ const HwcFenceControl& operator = (const HwcFenceControl& rhs) const;
+
+ int32_t mFenceFd;
+};
+
+}; // namespace amlogic
+}; // namespace android
+
+
+#endif // ANDROID_FENCE_H
diff --git a/hwc2/include/Hwcomposer.h b/hwc2/include/Hwcomposer.h
index cec6e74..02bd6a5 100644
--- a/hwc2/include/Hwcomposer.h
+++ b/hwc2/include/Hwcomposer.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef HWCOMPOSER_H
#define HWCOMPOSER_H
diff --git a/hwc2/include/IComposer.h b/hwc2/include/IComposer.h
new file mode 100644
index 0000000..f3b6fbe
--- a/dev/null
+++ b/hwc2/include/IComposer.h
@@ -0,0 +1,33 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+#ifndef ICOMPOSER_H
+#define ICOMPOSER_H
+
+#include <HwcLayer.h>
+
+namespace android {
+namespace amlogic {
+
+// aml composer interface
+class IComposer {
+public:
+ IComposer() {}
+ virtual ~IComposer() {}
+public:
+ virtual bool initialize(framebuffer_info_t* fbInfo) = 0;
+ virtual void deinitialize() = 0;
+ virtual int32_t startCompose(Vector< hwc2_layer_t > hwcLayers, int32_t *offset = 0, int32_t frameCount = 0) = 0;
+ virtual const char* getName() const = 0;
+ // virtual void setCurGlesFbSlot(uint32_t slot) = 0;
+ virtual const buffer_handle_t getBufHnd() = 0;
+ virtual void mergeRetireFence(int32_t slot, int32_t retireFence) = 0;
+ virtual void removeRetireFence(int32_t slot) = 0;
+ virtual void setVideoOverlayLayerId(hwc2_layer_t layerId) = 0;
+ virtual void fillRectangle(hwc_rect_t clipRect, uint32_t color, uint32_t addr) = 0;
+};
+
+}
+}
+
+#endif /* IDISPLAY_DEVICE_H */
diff --git a/hwc2/include/IComposerFactory.h b/hwc2/include/IComposerFactory.h
new file mode 100644
index 0000000..856e44c
--- a/dev/null
+++ b/hwc2/include/IComposerFactory.h
@@ -0,0 +1,25 @@
+/*
+// Copyright(c) 2016 Amlogic Corporation
+*/
+#ifndef ICOMPOSER_FACTORY_H_
+#define ICOMPOSER_FACTORY_H_
+
+
+#include <IComposer.h>
+
+namespace android {
+namespace amlogic {
+
+
+class IComposerFactory {
+
+public:
+ virtual ~IComposerFactory() {};
+
+public:
+ virtual IComposer* createComposer(String8 key) = 0;
+};
+} // namespace amlogic
+} // namespace android
+
+#endif /* ICOMPOSER_FACTORY_H_ */
diff --git a/hwc2/include/IDisplayDevice.h b/hwc2/include/IDisplayDevice.h
index fa297f4..7c4df71 100644
--- a/hwc2/include/IDisplayDevice.h
+++ b/hwc2/include/IDisplayDevice.h
@@ -1,9 +1,23 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef IDISPLAY_DEVICE_H
#define IDISPLAY_DEVICE_H
+#include <utils/KeyedVector.h>
#include <Dump.h>
#include <hardware/hwcomposer2.h>
#include <Hwcomposer.h>
@@ -12,6 +26,26 @@
namespace android {
namespace amlogic {
+enum {
+ LAYER_MAX_NUM_CHANGE_REQUEST = 8,
+ LAYER_MAX_NUM_CHANGE_TYPE = 16,
+ LAYER_MAX_NUM_SUPPORT = LAYER_MAX_NUM_CHANGE_TYPE,
+};
+
+enum {
+ GLES_COMPOSE_MODE = 0,
+ DIRECT_COMPOSE_MODE = 1,
+ GE2D_COMPOSE_MODE = 2,
+};
+
+enum {
+ GE2D_COMPOSE_NO_LAYER = 0,
+ GE2D_COMPOSE_ONE_LAYER = 1,
+ GE2D_COMPOSE_TWO_LAYERS = 2,
+ GE2D_COMPOSE_THREE_LAYERS = 3,
+ GE2D_COMPOSE_MAX_LAYERS = GE2D_COMPOSE_THREE_LAYERS,
+};
+
// display config
class DisplayConfig {
public:
diff --git a/hwc2/include/IPlatFactory.h b/hwc2/include/IPlatFactory.h
index 89ccf42..3122cf8 100644
--- a/hwc2/include/IPlatFactory.h
+++ b/hwc2/include/IPlatFactory.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef IPLATFORM_FACTORY_H_
#define IPLATFORM_FACTORY_H_
diff --git a/hwc2/include/PhysicalDevice.h b/hwc2/include/PhysicalDevice.h
index 85419f6..8efbd75 100644
--- a/hwc2/include/PhysicalDevice.h
+++ b/hwc2/include/PhysicalDevice.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef PHYSICAL_DEVICE_H
#define PHYSICAL_DEVICE_H
@@ -8,11 +21,12 @@
#include <SoftVsyncObserver.h>
#include <IDisplayDevice.h>
#include <HwcLayer.h>
+#include <IComposer.h>
namespace android {
namespace amlogic {
-class IHdcpControl;
+// class IHdcpControl;
typedef struct hdr_capabilities {
bool init;
@@ -27,23 +41,24 @@ class DeviceControlFactory {
public:
virtual ~DeviceControlFactory(){}
public:
- virtual IHdcpControl* createHdcpControl() = 0;
+ // virtual IHdcpControl* createHdcpControl() = 0;
+ virtual IComposer* createComposer(IDisplayDevice& disp) = 0;
};
-class CursorContext {
+class FBContext {
public:
- CursorContext()
+ FBContext()
: mStatus(false)
{
- mCursorInfo = new framebuffer_info_t();
+ mFBInfo = new framebuffer_info_t();
}
- virtual ~CursorContext(){}
+ virtual ~FBContext(){}
- virtual framebuffer_info_t* getCursorInfo() { return mCursorInfo; }
- virtual bool getCursorStatus() { return mStatus; }
- virtual void setCursorStatus(bool status) { mStatus = status; }
+ virtual framebuffer_info_t* getInfo() { return mFBInfo; }
+ virtual bool getStatus() { return mStatus; }
+ virtual void setStatus(bool status) { mStatus = status; }
private:
- framebuffer_info_t *mCursorInfo;
+ framebuffer_info_t *mFBInfo;
bool mStatus;
};
@@ -51,13 +66,8 @@ class Hwcomposer;
class SoftVsyncObserver;
class PhysicalDevice : public IDisplayDevice {
- enum {
- LAYER_MAX_NUM_CHANGE_REQUEST = 8,
- LAYER_MAX_NUM_CHANGE_TYPE = 16,
- LAYER_MAX_NUM_SUPPORT = LAYER_MAX_NUM_CHANGE_TYPE,
- };
public:
- PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc);
+ PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControlFactory* controlFactory);
~PhysicalDevice();
friend class Hwcomposer;
@@ -101,9 +111,9 @@ public:
virtual int32_t validateDisplay(uint32_t* outNumTypes, uint32_t* outNumRequests);
virtual int32_t setCursorPosition(hwc2_layer_t layerId, int32_t x, int32_t y);
- virtual int32_t createVirtualDisplay(uint32_t width, uint32_t height, int32_t* format, hwc2_display_t* outDisplay);
- virtual int32_t destroyVirtualDisplay(hwc2_display_t display);
- virtual int32_t setOutputBuffer(buffer_handle_t buffer, int32_t releaseFence);
+ virtual int32_t createVirtualDisplay(uint32_t width, uint32_t height, int32_t* format, hwc2_display_t* outDisplay) = 0;
+ virtual int32_t destroyVirtualDisplay(hwc2_display_t display) = 0;
+ virtual int32_t setOutputBuffer(buffer_handle_t buffer, int32_t releaseFence) = 0;
// Other Display methods
virtual Hwcomposer& getDevice() const { return mHwc; }
@@ -130,28 +140,58 @@ public:
private:
// For use by Device
int32_t initDisplay();
- int32_t postFramebuffer(int32_t* outRetireFence);
+ int32_t postFramebuffer(int32_t* outRetireFence, bool hasVideoOverlay);
int32_t getLineValue(const char *lineStr, const char *magicStr);
+
int32_t parseHdrCapabilities();
+ void directCompose(framebuffer_info_t * fbInfo);
+ void ge2dCompose(framebuffer_info_t * fbInfo, bool hasVideoOverlay);
+ int32_t setOSD0Blank(bool blank);
+ bool layersStateCheck(int32_t renderMode, KeyedVector<hwc2_layer_t, HwcLayer*> & composeLayers);
+ int32_t composersFilter(KeyedVector<hwc2_layer_t, HwcLayer*>& composeLayers);
+
+ //swap the mHwcCurReleaseFence and mHwcPriorReleaseFence;
+ void swapReleaseFence();
+ //this function will take contorl of fencefd, if you need use it also, please dup it before call.
+ void addReleaseFence(hwc2_layer_t layerId, int32_t fenceFd);
+ void clearFenceList(KeyedVector<hwc2_layer_t, int32_t> * fenceList);
+ void dumpFenceList(KeyedVector<hwc2_layer_t, int32_t> * fenceList);
+ void dumpLayers(Vector < hwc2_layer_t > layerIds);
+ void dumpLayers(KeyedVector<hwc2_layer_t, HwcLayer*> layers);
+ void clearFramebuffer();
+
+ template <typename T, typename S>
+ static inline bool compareSize(T a, S b) {
+ if ((int32_t)(a.right - a.left) == (int32_t)(b.right - b.left)
+ && (int32_t)(a.bottom - a.top) == (int32_t)(b.bottom - b.top)) {
+ return true;
+ }
+ return false;
+ }
// Member variables
hwc2_display_t mId;
const char *mName;
bool mIsConnected;
Hwcomposer& mHwc;
+ DeviceControlFactory *mControlFactory;
char mDisplayMode[32];
+ bool mOSD0Blank;
// display configs
Vector<DisplayConfig*> mDisplayConfigs;
int mActiveDisplayConfig;
SoftVsyncObserver *mVsyncObserver;
+ IComposer *mComposer;
// DeviceControlFactory *mControlFactory;
- framebuffer_info_t *mFramebufferInfo;
+ // framebuffer_info_t *mFramebufferInfo;
private_handle_t *mFramebufferHnd;
- CursorContext *mCursorContext;
+ FBContext *mCursorContext;
+ FBContext *mFramebufferContext;
+ int32_t mFbSlot;
int32_t /*android_color_mode_t*/ mColorMode;
@@ -161,7 +201,9 @@ private:
buffer_handle_t mClientTargetHnd;
hwc_region_t mClientTargetDamageRegion;
int32_t mTargetAcquireFence;
+ int32_t mGE2DComposeFrameCount;
int32_t mPriorFrameRetireFence;
+ int32_t mRenderMode;
bool mIsValidated;
// num of composition type changed layer.
@@ -169,13 +211,23 @@ private:
uint32_t mNumLayerChangerequest;
// layer
+ hwc2_layer_t mDirectRenderLayerId;
+ hwc2_layer_t mVideoOverlayLayerId;
+ int32_t mGE2DClearVideoRegionCount;
+ Vector< hwc2_layer_t > mGE2DRenderSortedLayerIds;
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayersChangeType;
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayersChangeRequest;
+ KeyedVector<hwc2_layer_t, HwcLayer*> mHwcGlesLayers;
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayers;
- //HDR Capabilities
+ // HDR Capabilities
hdr_capabilities_t mHdrCapabilities;
+ // record the release fence of layer.
+ KeyedVector<hwc2_layer_t, int32_t> mLayerReleaseFences[2];
+ KeyedVector<hwc2_layer_t, int32_t> * mHwcCurReleaseFences;
+ KeyedVector<hwc2_layer_t, int32_t> * mHwcPriorReleaseFences;
+
// lock
Mutex mLock;
bool mInitialized;
diff --git a/hwc2/include/PrimaryDevice.h b/hwc2/include/PrimaryDevice.h
index 136f6e6..777c305 100644
--- a/hwc2/include/PrimaryDevice.h
+++ b/hwc2/include/PrimaryDevice.h
@@ -1,11 +1,25 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#ifndef PRIMARY_DEVICE_H
#define PRIMARY_DEVICE_H
+#include <utils/KeyedVector.h>
#include <PhysicalDevice.h>
+#include <IComposerFactory.h>
namespace android {
namespace amlogic {
@@ -13,11 +27,14 @@ namespace amlogic {
class PrimaryDevice : public PhysicalDevice {
public:
- PrimaryDevice(Hwcomposer& hwc);
+ PrimaryDevice(Hwcomposer& hwc, DeviceControlFactory *composer);
virtual ~PrimaryDevice();
public:
virtual bool initialize();
virtual void deinitialize();
+ virtual int32_t createVirtualDisplay(uint32_t width, uint32_t height, int32_t* format, hwc2_display_t* outDisplay){ return HWC2_ERROR_NONE; }
+ virtual int32_t destroyVirtualDisplay(hwc2_display_t display) { return HWC2_ERROR_NONE; }
+ virtual int32_t setOutputBuffer(buffer_handle_t buffer, int32_t releaseFence) { return HWC2_ERROR_NONE; }
private:
static void hotplugInEventListener(void *data);
diff --git a/hwc2/include/UeventObserver.h b/hwc2/include/UeventObserver.h
index 48680bc..f5bcd55 100644
--- a/hwc2/include/UeventObserver.h
+++ b/hwc2/include/UeventObserver.h
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#ifndef UEVENT_OBSERVER_H
diff --git a/hwc2/include/VirtualDevice.h b/hwc2/include/VirtualDevice.h
index fc2b085..3c0670c 100644
--- a/hwc2/include/VirtualDevice.h
+++ b/hwc2/include/VirtualDevice.h
@@ -1,6 +1,19 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#ifndef VIRTUAL_DEVICE_H
#define VIRTUAL_DEVICE_H
diff --git a/hwc2/platforms/Android.mk b/hwc2/platforms/Android.mk
index b8d50da..5c2df1c 100644
--- a/hwc2/platforms/Android.mk
+++ b/hwc2/platforms/Android.mk
@@ -12,6 +12,7 @@ LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
../common/base/HwcLayer.cpp \
+ ../common/base/HwcFenceControl.cpp \
../common/base/Hwcomposer.cpp \
../common/base/HwcModule.cpp \
../common/base/VsyncManager.cpp \
@@ -20,6 +21,8 @@ LOCAL_SRC_FILES := \
../common/devices/VirtualDevice.cpp \
../common/observers/SoftVsyncObserver.cpp \
../common/observers/UeventObserver.cpp \
+ ../common/composers/Composers.cpp \
+ ../common/composers/GE2DComposer.cpp \
../common/utils/Utils.cpp \
../common/utils/Dump.cpp
@@ -34,13 +37,19 @@ LOCAL_SHARED_LIBRARIES := \
libhardware \
libutils \
libsync \
- libfbcnf
+ libion \
+ libfbcnf \
+ libge2d
-LOCAL_STATIC_LIBRARIES := libomxutil
+LOCAL_STATIC_LIBRARIES := \
+ libomxutil
LOCAL_C_INCLUDES := \
system/core \
- system/core/libsync/include
+ system/core/libsync \
+ system/core/libsync/include \
+ system/core/include \
+ vendor/amlogic/system/libge2d/inlcude
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
$(LOCAL_PATH)/../include \
@@ -50,6 +59,7 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH) \
$(LOCAL_PATH)/../common/observers \
$(LOCAL_PATH)/../common/planes \
$(LOCAL_PATH)/../common/utils \
+ $(LOCAL_PATH)/../common/composers \
$(LOCAL_PATH)/../.. \
$(LOCAL_PATH)/
@@ -73,6 +83,10 @@ LOCAL_C_INCLUDES += $(MESON_GRALLOC_DIR)
LOCAL_C_INCLUDES += system/core/libion/include/ \
system/core/libion/kernel-headers
+ifeq ($(TARGET_APP_LAYER_USE_CONTINUOUS_BUFFER),true)
+LOCAL_CFLAGS += -DUSE_CONTINOUS_BUFFER_COMPOSER
+endif
+
# WITH_LIBPLAYER_MODULE := true
ifneq ($(WITH_LIBPLAYER_MODULE),false)
LOCAL_SHARED_LIBRARIES += libamavutils_alsa
diff --git a/hwc2/platforms/PlatFactory.cpp b/hwc2/platforms/PlatFactory.cpp
index f5dda2f..921d29b 100644
--- a/hwc2/platforms/PlatFactory.cpp
+++ b/hwc2/platforms/PlatFactory.cpp
@@ -1,12 +1,26 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#include <HwcTrace.h>
#include <PrimaryDevice.h>
//#include <ExternalDevice.h>
#include <VirtualDevice.h>
#include <Hwcomposer.h>
#include <PlatFactory.h>
+#include <GE2DComposer.h>
namespace android {
namespace amlogic {
@@ -29,11 +43,12 @@ IDisplayDevice* PlatFactory::createDisplayDevice(int disp)
class PlatDeviceControlFactory: public DeviceControlFactory {
public:
+ virtual IComposer* createComposer(IDisplayDevice& disp) {return new GE2DComposer(disp);}
};
switch (disp) {
case IDisplayDevice::DEVICE_PRIMARY:
- return new PrimaryDevice(hwc);
+ return new PrimaryDevice(hwc, new PlatDeviceControlFactory());
case IDisplayDevice::DEVICE_VIRTUAL:
return new VirtualDevice(hwc);
case IDisplayDevice::DEVICE_EXTERNAL:
diff --git a/hwc2/platforms/PlatFactory.h b/hwc2/platforms/PlatFactory.h
index 75cd622..9f84c60 100644
--- a/hwc2/platforms/PlatFactory.h
+++ b/hwc2/platforms/PlatFactory.h
@@ -1,5 +1,17 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
#ifndef MOOFPLATFORMFACTORY_H_
diff --git a/hwc2/test/nv12_ved_test.cpp b/hwc2/test/nv12_ved_test.cpp
index 253c924..98e6a07 100644
--- a/hwc2/test/nv12_ved_test.cpp
+++ b/hwc2/test/nv12_ved_test.cpp
@@ -1,7 +1,20 @@
/*
-// Copyright (c) 2016 Amlogic Corporation
+// Copyright (c) 2014 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
*/
+
#include <gtest/gtest.h>
#include <binder/IMemory.h>