summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-11-22 23:49:35 +0000
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-12-12 22:55:12 +0000
commit6efc967ff5e0bb33a9116aee9846b041b80d0594 (patch)
tree0f0f49fbceb2d2ebfbea23801800fdd53fdf1648 /services
parent0a70c9c72dcce36e2a43937506af289c870707d7 (diff)
downloadframeworks_native-6efc967ff5e0bb33a9116aee9846b041b80d0594.zip
frameworks_native-6efc967ff5e0bb33a9116aee9846b041b80d0594.tar.gz
frameworks_native-6efc967ff5e0bb33a9116aee9846b041b80d0594.tar.bz2
Revert "remove support for HWC < 1.0"
This partially reverts commit 30bcc61431d8e3bef779472dd52a7b156dcaba09 and updates to the current API. Tested on 0.1 blobs from Tegra2/3 and OMAP3/4 Change-Id: I43cee8852b266d68d1edefbe7ac988b9dbcf7227
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp417
1 files changed, 343 insertions, 74 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 31d731e..690ec8d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -17,7 +17,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
// Uncomment this to remove support for HWC_DEVICE_API_VERSION_0_3 and older
-#define HWC_REMOVE_DEPRECATED_VERSIONS 1
+// #define HWC_REMOVE_DEPRECATED_VERSIONS 1
#include <stdint.h>
#include <stdio.h>
@@ -48,8 +48,28 @@
namespace android {
+// ---------------------------------------------------------------------------
+// Support for HWC_DEVICE_API_VERSION_0_3 and older:
+// Since v0.3 is deprecated and support will be dropped soon, as much as
+// possible the code is written to target v1.0. When using a v0.3 HWC, we
+// allocate v0.3 structures, but assign them to v1.0 pointers.
+
+#if HWC_REMOVE_DEPRECATED_VERSIONS
+// We need complete types to satisfy semantic checks, even though the code
+// paths that use these won't get executed at runtime (and will likely be dead-
+// code-eliminated). When we remove the code to support v0.3 we can remove
+// these as well.
+typedef hwc_layer_1_t hwc_layer_t;
+typedef hwc_display_contents_1_t hwc_layer_list_t;
+typedef hwc_composer_device_1_t hwc_composer_device_t;
+#endif
+
+// This function assumes we've already rejected HWC's with lower-than-required
+// versions. Don't use it for the initial "does HWC meet requirements" check!
+
#define MIN_HWC_HEADER_VERSION 0
+
static uint32_t hwcApiVersion(const hwc_composer_device_1_t* hwc) {
uint32_t hwcVersion = hwc->common.version;
if (MIN_HWC_HEADER_VERSION == 0 &&
@@ -75,6 +95,106 @@ static bool hwcHasApiVersion(const hwc_composer_device_1_t* hwc,
return hwcApiVersion(hwc) >= (version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK);
}
+static bool hwcHasVsyncEvent(const hwc_composer_device_1_t* hwc) {
+ return hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_0_3);
+}
+
+static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc,
+ size_t numLayers) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return sizeof(hwc_display_contents_1_t) + numLayers*sizeof(hwc_layer_1_t);
+ } else {
+ return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t);
+ }
+}
+
+static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy,
+ int event, int enabled) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return hwc->eventControl(hwc, dpy, event, enabled);
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ return hwc0->methods->eventControl(hwc0, event, enabled);
+ }
+}
+
+static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return hwc->blank(hwc, dpy, blank);
+ } else {
+ if (blank) {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ return hwc0->set(hwc0, NULL, NULL, NULL);
+ } else {
+ // HWC 0.x turns the screen on at the next set()
+ return NO_ERROR;
+ }
+ }
+}
+
+static int hwcPrepare(hwc_composer_device_1_t* hwc,
+ size_t numDisplays, hwc_display_contents_1_t** displays) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return hwc->prepare(hwc, numDisplays, displays);
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
+ // In the past, SurfaceFlinger would pass a NULL list when doing full
+ // OpenGL ES composition. I don't know what, if any, dependencies there
+ // are on this behavior, so I'm playing it safe and preserving it.
+ // ... and I'm removing it. NULL layers kill the Tegra compositor (RC, Nov 2012)
+ /*if (list0->numHwLayers == 0)
+ return hwc0->prepare(hwc0, NULL);
+ else*/
+ return hwc0->prepare(hwc0, list0);
+ }
+}
+static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur,
+ size_t numDisplays, hwc_display_contents_1_t** displays) {
+ int err;
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ displays[0]->dpy = dpy;
+ displays[0]->sur = sur;
+ err = hwc->set(hwc, numDisplays, displays);
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
+ err = hwc0->set(hwc0, dpy, sur, list0);
+ }
+ return err;
+}
+
+static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc,
+ hwc_display_contents_1_t* display) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return display->flags;
+ } else {
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
+ return list0->flags;
+ }
+}
+
+static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc,
+ hwc_display_contents_1_t* display) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return display->numHwLayers;
+ } else {
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
+ return list0->numHwLayers;
+ }
+}
+
+static void hwcDump(hwc_composer_device_1_t* hwc, char* buff, int buff_len) {
+ if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (hwc->dump)
+ hwc->dump(hwc, buff, buff_len);
+ } else if (hwcHasApiVersion(hwc, HWC_DEVICE_API_VERSION_0_1)) {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
+ if (hwc0->dump)
+ hwc0->dump(hwc0, buff, buff_len);
+ }
+}
+
// ---------------------------------------------------------------------------
struct HWComposer::cb_context {
@@ -137,32 +257,48 @@ HWComposer::HWComposer(
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
(hwcApiVersion(mHwc) >> 24) & 0xff,
(hwcApiVersion(mHwc) >> 16) & 0xff);
- if (mHwc->registerProcs) {
- mCBContext->hwc = this;
- mCBContext->procs.invalidate = &hook_invalidate;
- mCBContext->procs.vsync = &hook_vsync;
- if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
- mCBContext->procs.hotplug = &hook_hotplug;
- else
- mCBContext->procs.hotplug = NULL;
- memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
- mHwc->registerProcs(mHwc, &mCBContext->procs);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (mHwc->registerProcs) {
+ mCBContext->hwc = this;
+ mCBContext->procs.invalidate = &hook_invalidate;
+ mCBContext->procs.vsync = &hook_vsync;
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
+ mCBContext->procs.hotplug = &hook_hotplug;
+ else
+ mCBContext->procs.hotplug = NULL;
+ memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
+ mHwc->registerProcs(mHwc, &mCBContext->procs);
+ }
+ } else {
+ hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(mHwc);
+ if (hwc0->registerProcs) {
+ mCBContext->hwc = this;
+ mCBContext->procs.invalidate = &hook_invalidate;
+ mCBContext->procs.vsync = &hook_vsync;
+ memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
+ hwc0->registerProcs(hwc0, &mCBContext->procs);
+ }
}
// don't need a vsync thread if we have a hardware composer
needVSyncThread = false;
// always turn vsync off when we start
- eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
+ if (hwcHasVsyncEvent(mHwc)) {
+ eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
- // the number of displays we actually have depends on the
- // hw composer version
- if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
- // 1.2 adds support for virtual displays
- mNumDisplays = MAX_DISPLAYS;
- } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
- // 1.1 adds support for multiple displays
- mNumDisplays = HWC_NUM_DISPLAY_TYPES;
+ // the number of displays we actually have depends on the
+ // hw composer version
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
+ // 1.2 adds support for virtual displays
+ mNumDisplays = MAX_DISPLAYS;
+ } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
+ // 1.1 adds support for multiple displays
+ mNumDisplays = HWC_NUM_DISPLAY_TYPES;
+ } else {
+ mNumDisplays = 1;
+ }
} else {
+ needVSyncThread = true;
mNumDisplays = 1;
}
}
@@ -233,9 +369,10 @@ void HWComposer::loadHwcModule()
return;
}
- if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
+ if (HWC_REMOVE_DEPRECATED_VERSIONS &&
+ (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0) ||
hwcHeaderVersion(mHwc) < MIN_HWC_HEADER_VERSION ||
- hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION) {
+ hwcHeaderVersion(mHwc) > HWC_HEADER_VERSION)) {
ALOGE("%s device version %#x unsupported, will not be used",
HWC_HARDWARE_COMPOSER, mHwc->common.version);
hwc_close_1(mHwc);
@@ -455,22 +592,26 @@ void HWComposer::eventControl(int disp, int event, int enabled) {
return;
}
status_t err = NO_ERROR;
- if (mHwc && !mDebugForceFakeVSync) {
- // NOTE: we use our own internal lock here because we have to call
- // into the HWC with the lock held, and we want to make sure
- // that even if HWC blocks (which it shouldn't), it won't
- // affect other threads.
- Mutex::Autolock _l(mEventControlLock);
- const int32_t eventBit = 1UL << event;
- const int32_t newValue = enabled ? eventBit : 0;
- const int32_t oldValue = mDisplayData[disp].events & eventBit;
- if (newValue != oldValue) {
- ATRACE_CALL();
- err = mHwc->eventControl(mHwc, disp, event, enabled);
- if (!err) {
- int32_t& events(mDisplayData[disp].events);
- events = (events & ~eventBit) | newValue;
+ if (mHwc && !mDebugForceFakeVSync && hwcHasVsyncEvent(mHwc)) {
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ // NOTE: we use our own internal lock here because we have to call
+ // into the HWC with the lock held, and we want to make sure
+ // that even if HWC blocks (which it shouldn't), it won't
+ // affect other threads.
+ Mutex::Autolock _l(mEventControlLock);
+ const int32_t eventBit = 1UL << event;
+ const int32_t newValue = enabled ? eventBit : 0;
+ const int32_t oldValue = mDisplayData[disp].events & eventBit;
+ if (newValue != oldValue) {
+ ATRACE_CALL();
+ err = hwcEventControl(mHwc, disp, event, enabled);
+ if (!err) {
+ int32_t& events(mDisplayData[disp].events);
+ events = (events & ~eventBit) | newValue;
+ }
}
+ } else {
+ err = hwcEventControl(mHwc, disp, event, enabled);
}
// error here should not happen -- not sure what we should
// do if it does.
@@ -495,8 +636,7 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
numLayers++;
}
if (disp.capacity < numLayers || disp.list == NULL) {
- size_t size = sizeof(hwc_display_contents_1_t)
- + numLayers * sizeof(hwc_layer_1_t);
+ size_t size = sizeofHwcLayerList(mHwc, numLayers);
free(disp.list);
disp.list = (hwc_display_contents_1_t*)malloc(size);
disp.capacity = numLayers;
@@ -519,9 +659,11 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
disp.framebufferTarget->acquireFenceFd = -1;
disp.framebufferTarget->releaseFenceFd = -1;
}
- disp.list->retireFenceFd = -1;
- disp.list->flags = HWC_GEOMETRY_CHANGED;
- disp.list->numHwLayers = numLayers;
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ disp.list->retireFenceFd = -1;
+ }
+ hwcFlags(mHwc, disp.list) = HWC_GEOMETRY_CHANGED;
+ hwcNumHwLayers(mHwc, disp.list) = numLayers;
}
return NO_ERROR;
}
@@ -568,7 +710,7 @@ status_t HWComposer::prepare() {
}
if (!disp.connected && disp.list != NULL) {
ALOGW("WARNING: disp %d: connected, non-null list, layers=%d",
- i, disp.list->numHwLayers);
+ i, hwcNumHwLayers(mHwc, disp.list));
}
mLists[i] = disp.list;
if (mLists[i]) {
@@ -579,27 +721,51 @@ status_t HWComposer::prepare() {
// garbage data to catch improper use
mLists[i]->dpy = (hwc_display_t)0xDEADBEEF;
mLists[i]->sur = (hwc_surface_t)0xDEADBEEF;
- } else {
+ } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
mLists[i]->dpy = EGL_NO_DISPLAY;
mLists[i]->sur = EGL_NO_SURFACE;
}
}
}
-
- int err = mHwc->prepare(mHwc, mNumDisplays, mLists);
+ int err = hwcPrepare(mHwc, mNumDisplays, mLists);
ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err));
if (err == NO_ERROR) {
- // here we're just making sure that "skip" layers are set
- // to HWC_FRAMEBUFFER and we're also counting how many layers
- // we have of each type.
- for (size_t i=0 ; i<mNumDisplays ; i++) {
- DisplayData& disp(mDisplayData[i]);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ // here we're just making sure that "skip" layers are set
+ // to HWC_FRAMEBUFFER and we're also counting how many layers
+ // we have of each type.
+ for (size_t i=0 ; i<mNumDisplays ; i++) {
+ DisplayData& disp(mDisplayData[i]);
+ disp.hasFbComp = false;
+ disp.hasOvComp = false;
+ if (disp.list) {
+ for (size_t i=0 ; i<hwcNumHwLayers(mHwc, disp.list) ; i++) {
+ hwc_layer_1_t& l = disp.list->hwLayers[i];
+
+ //ALOGD("prepare: %d, type=%d, handle=%p",
+ // i, l.compositionType, l.handle);
+
+ if (l.flags & HWC_SKIP_LAYER) {
+ l.compositionType = HWC_FRAMEBUFFER;
+ }
+ if (l.compositionType == HWC_FRAMEBUFFER) {
+ disp.hasFbComp = true;
+ }
+ if (l.compositionType == HWC_OVERLAY) {
+ disp.hasOvComp = true;
+ }
+ }
+ }
+ }
+ } else {
+ DisplayData& disp(mDisplayData[0]);
disp.hasFbComp = false;
disp.hasOvComp = false;
if (disp.list) {
- for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
- hwc_layer_1_t& l = disp.list->hwLayers[i];
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(disp.list);
+ for (size_t i=0 ; i<hwcNumHwLayers(mHwc, disp.list) ; i++) {
+ hwc_layer_t& l = list0->hwLayers[i];
//ALOGD("prepare: %d, type=%d, handle=%p",
// i, l.compositionType, l.handle);
@@ -615,7 +781,9 @@ status_t HWComposer::prepare() {
}
}
}
+
}
+
}
return (status_t)err;
}
@@ -651,24 +819,32 @@ int HWComposer::getAndResetReleaseFenceFd(int32_t id) {
status_t HWComposer::commit() {
int err = NO_ERROR;
if (mHwc) {
- if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
- // On version 1.0, the OpenGL ES target surface is communicated
- // by the (dpy, sur) fields and we are guaranteed to have only
- // a single display.
- mLists[0]->dpy = eglGetCurrentDisplay();
- mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
+ // On version 1.0, the OpenGL ES target surface is communicated
+ // by the (dpy, sur) fields and we are guaranteed to have only
+ // a single display.
+ mLists[0]->dpy = eglGetCurrentDisplay();
+ mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
+ }
+ err = hwcSet(mHwc, mLists[0]->dpy, mLists[0]->sur, mNumDisplays,
+ const_cast<hwc_display_contents_1_t**>(mLists));
+ } else {
+ err = hwcSet(mHwc, eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), mNumDisplays,
+ const_cast<hwc_display_contents_1_t**>(mLists));
}
- err = mHwc->set(mHwc, mNumDisplays, mLists);
for (size_t i=0 ; i<mNumDisplays ; i++) {
DisplayData& disp(mDisplayData[i]);
if (disp.list) {
- if (disp.list->retireFenceFd != -1) {
- close(disp.list->retireFenceFd);
- disp.list->retireFenceFd = -1;
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ if (disp.list->retireFenceFd != -1) {
+ close(disp.list->retireFenceFd);
+ disp.list->retireFenceFd = -1;
+ }
}
- disp.list->flags &= ~HWC_GEOMETRY_CHANGED;
+ hwcFlags(mHwc, disp.list) &= ~HWC_GEOMETRY_CHANGED;
}
}
}
@@ -678,8 +854,10 @@ status_t HWComposer::commit() {
status_t HWComposer::release(int disp) {
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
if (mHwc) {
- eventControl(disp, HWC_EVENT_VSYNC, 0);
- return (status_t)mHwc->blank(mHwc, disp, 1);
+ if (hwcHasVsyncEvent(mHwc)) {
+ eventControl(disp, HWC_EVENT_VSYNC, 0);
+ }
+ return (status_t)hwcBlank(mHwc, disp, 1);
}
return NO_ERROR;
}
@@ -687,7 +865,7 @@ status_t HWComposer::release(int disp) {
status_t HWComposer::acquire(int disp) {
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
if (mHwc) {
- return (status_t)mHwc->blank(mHwc, disp, 0);
+ return (status_t)hwcBlank(mHwc, disp, 0);
}
return NO_ERROR;
}
@@ -780,6 +958,93 @@ private:
}
};
+// #if !HWC_REMOVE_DEPRECATED_VERSIONS
+/*
+ * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
+ * This implements the HWCLayer side of HWCIterableLayer.
+ */
+class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
+public:
+ HWCLayerVersion0(hwc_layer_t* layer)
+ : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
+
+ virtual int32_t getCompositionType() const {
+ return getLayer()->compositionType;
+ }
+ virtual uint32_t getHints() const {
+ return getLayer()->hints;
+ }
+ virtual int getAndResetReleaseFenceFd() {
+ // not supported on VERSION_03
+ return -1;
+ }
+ virtual void setAcquireFenceFd(int fenceFd) {
+ if (fenceFd != -1) {
+ ALOGE("HWC 0.x can't handle acquire fences");
+ close(fenceFd);
+ }
+ }
+
+ virtual void setDefaultState() {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->hints = 0;
+ getLayer()->flags = HWC_SKIP_LAYER;
+ getLayer()->handle = 0;
+ getLayer()->transform = 0;
+ getLayer()->blending = HWC_BLENDING_NONE;
+ getLayer()->visibleRegionScreen.numRects = 0;
+ getLayer()->visibleRegionScreen.rects = NULL;
+ }
+ virtual void setSkip(bool skip) {
+ if (skip) {
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ } else {
+ getLayer()->flags &= ~HWC_SKIP_LAYER;
+ }
+ }
+ virtual void setBlending(uint32_t blending) {
+ getLayer()->blending = blending;
+ }
+ virtual void setTransform(uint32_t transform) {
+ getLayer()->transform = transform;
+ }
+ virtual void setFrame(const Rect& frame) {
+ reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
+ }
+ virtual void setCrop(const Rect& crop) {
+ reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
+ }
+ virtual void setVisibleRegionScreen(const Region& reg) {
+ // Region::getSharedBuffer creates a reference to the underlying
+ // SharedBuffer of this Region, this reference is freed
+ // in onDisplayed()
+ hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
+ SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
+ visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
+ }
+ virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
+ if (buffer == 0 || buffer->handle == 0) {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ getLayer()->handle = 0;
+ } else {
+ getLayer()->handle = buffer->handle;
+ }
+ }
+ virtual void onDisplayed() {
+ hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
+ SharedBuffer const* sb = SharedBuffer::bufferFromData(visibleRegion.rects);
+ if (sb) {
+ sb->release();
+ // not technically needed but safer
+ visibleRegion.numRects = 0;
+ visibleRegion.rects = NULL;
+ }
+
+ }
+};
+// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
+
/*
* Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
* This implements the HWCLayer side of HWCIterableLayer.
@@ -874,10 +1139,15 @@ HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t in
return LayerListIterator();
}
const DisplayData& disp(mDisplayData[id]);
- if (!mHwc || !disp.list || index > disp.list->numHwLayers) {
+ if (!mHwc || !disp.list || index > hwcNumHwLayers(mHwc,disp.list)) {
return LayerListIterator();
}
- return LayerListIterator(new HWCLayerVersion1(disp.list->hwLayers), index);
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
+ return LayerListIterator(new HWCLayerVersion1(disp.list->hwLayers), index);
+ } else {
+ hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(disp.list);
+ return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
+ }
}
/*
@@ -895,7 +1165,7 @@ HWComposer::LayerListIterator HWComposer::end(int32_t id) {
if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) {
const DisplayData& disp(mDisplayData[id]);
if (mHwc && disp.list) {
- numLayers = disp.list->numHwLayers;
+ numLayers = hwcNumHwLayers(mHwc, disp.list);
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET,
// which we ignore when iterating through the layer list.
@@ -977,9 +1247,8 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
}
}
}
-
- if (mHwc && mHwc->dump) {
- mHwc->dump(mHwc, buffer, SIZE);
+ if (mHwc) {
+ hwcDump(mHwc, buffer, SIZE);
result.append(buffer);
}
}
@@ -1033,7 +1302,7 @@ bool HWComposer::VSyncThread::threadLoop() {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
- if (err == 0) {
+ if (err == 0 && mEnabled) {
mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
}