diff options
author | 2012-07-31 14:32:56 -0700 | |
---|---|---|
committer | 2012-08-07 12:16:36 -0700 | |
commit | b685c542836b93c99cd85053e07696406ea37adb (patch) | |
tree | 9907e7f794f0d96ae2a43894a9efab73a695c104 | |
parent | 14bd369e4b711bfb267279c2161358542ed75b29 (diff) |
Changes to support multi-display HWC
Change-Id: I07efff54f2980dcb013935747b03e099b8f1181b
-rw-r--r-- | opengl/tests/hwc/hwcColorEquiv.cpp | 12 | ||||
-rw-r--r-- | opengl/tests/hwc/hwcCommit.cpp | 4 | ||||
-rw-r--r-- | opengl/tests/hwc/hwcRects.cpp | 8 | ||||
-rw-r--r-- | opengl/tests/hwc/hwcStress.cpp | 8 | ||||
-rw-r--r-- | opengl/tests/hwc/hwcTestLib.cpp | 16 | ||||
-rw-r--r-- | opengl/tests/hwc/hwcTestLib.h | 10 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 211 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 9 |
8 files changed, 186 insertions, 92 deletions
diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp index ab5277eec8..160906ddbb 100644 --- a/opengl/tests/hwc/hwcColorEquiv.cpp +++ b/opengl/tests/hwc/hwcColorEquiv.cpp @@ -344,9 +344,9 @@ main(int argc, char *argv[]) hwcTestFillColorHBlend(equivFrame.get(), refFormat->format, startRefColor, endRefColor); - hwc_layer_list_1_t *list; - size_t size = sizeof(hwc_layer_list_1_t) + numFrames * sizeof(hwc_layer_1_t); - if ((list = (hwc_layer_list_1_t *) calloc(1, size)) == NULL) { + hwc_display_contents_1_t *list; + size_t size = sizeof(hwc_display_contents_1_t) + numFrames * sizeof(hwc_layer_1_t); + if ((list = (hwc_display_contents_1_t *) calloc(1, size)) == NULL) { testPrintE("Allocate list failed"); exit(11); } @@ -383,7 +383,7 @@ main(int argc, char *argv[]) // Perform prepare operation if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); } - hwcDevice->prepare(hwcDevice, list); + hwcDevice->prepare(hwcDevice, 1, &list); if (verbose) { testPrintI("Post Prepare:"); hwcTestDisplayListPrepareModifiable(list); @@ -393,7 +393,9 @@ main(int argc, char *argv[]) list->flags &= ~HWC_GEOMETRY_CHANGED; if (verbose) {hwcTestDisplayListHandles(list); } - hwcDevice->set(hwcDevice, dpy, surface, list); + list->dpy = dpy; + list->sur = surface; + hwcDevice->set(hwcDevice, 1, &list); testDelay(endDelay); diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp index d4873d8dc1..3681fbbe9f 100644 --- a/opengl/tests/hwc/hwcCommit.cpp +++ b/opengl/tests/hwc/hwcCommit.cpp @@ -1397,7 +1397,7 @@ void Rational::double2Rational(double f, Range nRange, Range dRange, // Given a list of rectangles, determine how many HWC will commit to render uint32_t numOverlays(list<Rectangle>& rectList) { - hwc_layer_list_1_t *hwcList; + hwc_display_contents_1_t *hwcList; list<sp<GraphicBuffer> > buffers; hwcList = hwcTestCreateLayerList(rectList.size()); @@ -1430,7 +1430,7 @@ uint32_t numOverlays(list<Rectangle>& rectList) // Perform prepare operation if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(hwcList); } - hwcDevice->prepare(hwcDevice, hwcList); + hwcDevice->prepare(hwcDevice, 1, &hwcList); if (verbose) { testPrintI("Post Prepare:"); hwcTestDisplayListPrepareModifiable(hwcList); diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp index e2f0039800..ec0403f6e5 100644 --- a/opengl/tests/hwc/hwcRects.cpp +++ b/opengl/tests/hwc/hwcRects.cpp @@ -307,7 +307,7 @@ main(int argc, char *argv[]) } // Create list of frames - hwc_layer_list_1_t *list; + hwc_display_contents_1_t *list; list = hwcTestCreateLayerList(rectangle.size()); if (list == NULL) { testPrintE("hwcTestCreateLayerList failed"); @@ -329,7 +329,7 @@ main(int argc, char *argv[]) // Perform prepare operation if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); } - hwcDevice->prepare(hwcDevice, list); + hwcDevice->prepare(hwcDevice, 1, &list); if (verbose) { testPrintI("Post Prepare:"); hwcTestDisplayListPrepareModifiable(list); @@ -341,7 +341,9 @@ main(int argc, char *argv[]) // Perform the set operation(s) if (verbose) {testPrintI("Set:"); } if (verbose) { hwcTestDisplayListHandles(list); } - hwcDevice->set(hwcDevice, dpy, surface, list); + list->dpy = dpy; + list->sur = surface; + hwcDevice->set(hwcDevice, 1, &list); testDelay(endDelay); diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp index ccc7328432..3e8ea8dba6 100644 --- a/opengl/tests/hwc/hwcStress.cpp +++ b/opengl/tests/hwc/hwcStress.cpp @@ -409,7 +409,7 @@ main(int argc, char *argv[]) // generated for this pass. srand48(pass); - hwc_layer_list_1_t *list; + hwc_display_contents_1_t *list; list = hwcTestCreateLayerList(testRandMod(frames.size()) + 1); if (list == NULL) { testPrintE("hwcTestCreateLayerList failed"); @@ -478,7 +478,7 @@ main(int argc, char *argv[]) // Perform prepare operation if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); } - hwcDevice->prepare(hwcDevice, list); + hwcDevice->prepare(hwcDevice, 1, &list); if (verbose) { testPrintI("Post Prepare:"); hwcTestDisplayListPrepareModifiable(list); @@ -491,7 +491,9 @@ main(int argc, char *argv[]) if (verbose) {testPrintI("Set:"); } for (unsigned int n1 = 0; n1 < numSet; n1++) { if (verbose) { hwcTestDisplayListHandles(list); } - hwcDevice->set(hwcDevice, dpy, surface, list); + list->dpy = dpy; + list->sur = surface; + hwcDevice->set(hwcDevice, 1, &list); // Prandomly select a new set of handles for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { diff --git a/opengl/tests/hwc/hwcTestLib.cpp b/opengl/tests/hwc/hwcTestLib.cpp index c6dbe9dcb2..d567e6eb31 100644 --- a/opengl/tests/hwc/hwcTestLib.cpp +++ b/opengl/tests/hwc/hwcTestLib.cpp @@ -399,12 +399,12 @@ const char *hwcTestGraphicFormat2str(uint32_t format) * Dynamically creates layer list with numLayers worth * of hwLayers entries. */ -hwc_layer_list_1_t *hwcTestCreateLayerList(size_t numLayers) +hwc_display_contents_1_t *hwcTestCreateLayerList(size_t numLayers) { - hwc_layer_list_1_t *list; + hwc_display_contents_1_t *list; - size_t size = sizeof(hwc_layer_list_1_t) + numLayers * sizeof(hwc_layer_1_t); - if ((list = (hwc_layer_list_1_t *) calloc(1, size)) == NULL) { + size_t size = sizeof(hwc_display_contents_1_t) + numLayers * sizeof(hwc_layer_1_t); + if ((list = (hwc_display_contents_1_t *) calloc(1, size)) == NULL) { return NULL; } list->flags = HWC_GEOMETRY_CHANGED; @@ -417,13 +417,13 @@ hwc_layer_list_1_t *hwcTestCreateLayerList(size_t numLayers) * hwcTestFreeLayerList * Frees memory previous allocated via hwcTestCreateLayerList(). */ -void hwcTestFreeLayerList(hwc_layer_list_1_t *list) +void hwcTestFreeLayerList(hwc_display_contents_1_t *list) { free(list); } // Display the settings of the layer list pointed to by list -void hwcTestDisplayList(hwc_layer_list_1_t *list) +void hwcTestDisplayList(hwc_display_contents_1_t *list) { testPrintI(" flags: %#x%s", list->flags, (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : ""); @@ -494,7 +494,7 @@ void hwcTestDisplayList(hwc_layer_list_1_t *list) * Displays the portions of a list that are meant to be modified by * a prepare call. */ -void hwcTestDisplayListPrepareModifiable(hwc_layer_list_1_t *list) +void hwcTestDisplayListPrepareModifiable(hwc_display_contents_1_t *list) { uint32_t numOverlays = 0; for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { @@ -522,7 +522,7 @@ void hwcTestDisplayListPrepareModifiable(hwc_layer_list_1_t *list) * * Displays the handles of all the graphic buffers in the list. */ -void hwcTestDisplayListHandles(hwc_layer_list_1_t *list) +void hwcTestDisplayListHandles(hwc_display_contents_1_t *list) { const unsigned int maxLayersPerLine = 6; diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h index db3f5c12f6..d7d5837ba9 100644 --- a/opengl/tests/hwc/hwcTestLib.h +++ b/opengl/tests/hwc/hwcTestLib.h @@ -113,11 +113,11 @@ const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id); const char *hwcTestGraphicFormat2str(uint32_t format); std::string hwcTestRect2str(const struct hwc_rect& rect); -hwc_layer_list_1_t *hwcTestCreateLayerList(size_t numLayers); -void hwcTestFreeLayerList(hwc_layer_list_1_t *list); -void hwcTestDisplayList(hwc_layer_list_1_t *list); -void hwcTestDisplayListPrepareModifiable(hwc_layer_list_1_t *list); -void hwcTestDisplayListHandles(hwc_layer_list_1_t *list); +hwc_display_contents_1_t *hwcTestCreateLayerList(size_t numLayers); +void hwcTestFreeLayerList(hwc_display_contents_1_t *list); +void hwcTestDisplayList(hwc_display_contents_1_t *list); +void hwcTestDisplayListPrepareModifiable(hwc_display_contents_1_t *list); +void hwcTestDisplayListHandles(hwc_display_contents_1_t *list); uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha); void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat, diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 2a51fb66c6..40ce90b9aa 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -50,17 +50,15 @@ 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. Fields that -// exist in both versions are located at the same offset, so in most cases we -// can just use the v1.0 pointer without branches or casts. +// allocate v0.3 structures, but assign them to v1.0 pointers. #if HWC_REMOVE_DEPRECATED_VERSIONS -// We need complete types with 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 +// 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_layer_list_1_t hwc_layer_list_t; +typedef hwc_display_contents_1_t hwc_layer_list_t; typedef hwc_composer_device_1_t hwc_composer_device_t; #endif @@ -75,15 +73,97 @@ static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) } } +static bool hwcHasVsyncEvent(const hwc_composer_device_1_t* hwc) { + return hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_0_3); +} + static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc, size_t numLayers) { if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { - return sizeof(hwc_layer_list_1_t) + numLayers*sizeof(hwc_layer_1_t); + 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 (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { + return hwc->methods->eventControl(hwc, dpy, event, enabled); + } else { + hwc_composer_device_t* hwc0 = (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 (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { + return hwc->methods->blank(hwc, dpy, blank); + } else { + if (blank) { + hwc_composer_device_t* hwc0 = (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 (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { + return hwc->prepare(hwc, numDisplays, displays); + } else { + hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; + hwc_layer_list_t* list0 = (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. + 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 (hwcHasVersion(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 = (hwc_composer_device_t*)hwc; + hwc_layer_list_t* list0 = (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 (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { + return display->flags; + } else { + hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; + hwc_layer_list_t* list0 = (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 (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { + return display->numHwLayers; + } else { + hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; + hwc_layer_list_t* list0 = (hwc_layer_list_t*)display; + return list0->numHwLayers; + } +} + // --------------------------------------------------------------------------- struct HWComposer::cb_context { @@ -103,12 +183,15 @@ HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), - mModule(0), mHwc(0), mList(0), mCapacity(0), + mModule(0), mHwc(0), mCapacity(0), mNumOVLayers(0), mNumFBLayers(0), mCBContext(new cb_context), mEventHandler(handler), mRefreshPeriod(0), mVSyncCount(0), mDebugForceFakeVSync(false) { + for (size_t i = 0; i < MAX_DISPLAYS; i++) + mLists[i] = NULL; + char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.no_hw_vsync", value, "0"); mDebugForceFakeVSync = atoi(value); @@ -131,16 +214,19 @@ HWComposer::HWComposer( } if (mHwc) { - if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) { - // always turn vsync off when we start - mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); - needVSyncThread = false; + // always turn vsync off when we start + needVSyncThread = false; + if (hwcHasVsyncEvent(mHwc)) { + hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0); int period; if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) { mRefreshPeriod = nsecs_t(period); } + } else { + needVSyncThread = true; } + if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; @@ -148,6 +234,9 @@ HWComposer::HWComposer( mHwc->registerProcs(mHwc, &mCBContext->procs); memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); } + + // create initial empty display contents for display 0 + createWorkList(0); } } @@ -178,8 +267,9 @@ HWComposer::HWComposer( } HWComposer::~HWComposer() { - eventControl(EVENT_VSYNC, 0); - free(mList); + hwcEventControl(mHwc, 0, EVENT_VSYNC, 0); + for (size_t i = 0; i < MAX_DISPLAYS; i++) + free(mLists[i]); if (mVSyncThread != NULL) { mVSyncThread->requestExitAndWait(); } @@ -229,7 +319,7 @@ void HWComposer::eventControl(int event, int enabled) { status_t err = NO_ERROR; if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { if (!mDebugForceFakeVSync) { - err = mHwc->methods->eventControl(mHwc, event, enabled); + err = hwcEventControl(mHwc, 0, event, enabled); // error here should not happen -- not sure what we should // do if it does. ALOGE_IF(err, "eventControl(%d, %d) failed %s", @@ -244,32 +334,37 @@ void HWComposer::eventControl(int event, int enabled) { status_t HWComposer::createWorkList(size_t numLayers) { if (mHwc) { - if (!mList || mCapacity < numLayers) { - free(mList); + // mLists[0] is NULL only when this is called from the constructor + if (!mLists[0] || mCapacity < numLayers) { + free(mLists[0]); size_t size = sizeofHwcLayerList(mHwc, numLayers); - mList = (hwc_layer_list_1_t*)malloc(size); + mLists[0] = (hwc_display_contents_1_t*)malloc(size); mCapacity = numLayers; } - mList->flags = HWC_GEOMETRY_CHANGED; - mList->numHwLayers = numLayers; + hwcFlags(mHwc, mLists[0]) = HWC_GEOMETRY_CHANGED; + hwcNumHwLayers(mHwc, mLists[0]) = numLayers; + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + mLists[0]->flipFenceFd = -1; + } } return NO_ERROR; } status_t HWComposer::prepare() const { - int err = mHwc->prepare(mHwc, mList); + int err = hwcPrepare(mHwc, 1, + const_cast<hwc_display_contents_1_t**>(mLists)); if (err == NO_ERROR) { size_t numOVLayers = 0; size_t numFBLayers = 0; - size_t count = mList->numHwLayers; + size_t count = getNumLayers(); for (size_t i=0 ; i<count ; i++) { hwc_layer_1_t* l = NULL; if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { - l = &mList->hwLayers[i]; + l = &mLists[0]->hwLayers[i]; } else { // mList really has hwc_layer_list_t memory layout - hwc_layer_list_t* list = (hwc_layer_list_t*)mList; - hwc_layer_t* layer = &list->hwLayers[i]; + hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; + hwc_layer_t* layer = &list0->hwLayers[i]; l = (hwc_layer_1_t*)layer; } if (l->flags & HWC_SKIP_LAYER) { @@ -303,59 +398,47 @@ size_t HWComposer::getLayerCount(int type) const { status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const { int err = NO_ERROR; if (mHwc) { - err = mHwc->set(mHwc, fbDisplay, fbSurface, mList); - if (mList) { - mList->flags &= ~HWC_GEOMETRY_CHANGED; + err = hwcSet(mHwc, fbDisplay, fbSurface, 1, + const_cast<hwc_display_contents_1_t**>(mLists)); + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + if (mLists[0]->flipFenceFd != -1) { + close(mLists[0]->flipFenceFd); + mLists[0]->flipFenceFd = -1; + } } + hwcFlags(mHwc, mLists[0]) &= ~HWC_GEOMETRY_CHANGED; } return (status_t)err; } status_t HWComposer::release() const { if (mHwc) { - if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) { - mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); - } - int err = mHwc->set(mHwc, NULL, NULL, NULL); - if (err < 0) { - return (status_t)err; + if (hwcHasVsyncEvent(mHwc)) { + hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0); } - - if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { - if (mHwc->methods && mHwc->methods->blank) { - err = mHwc->methods->blank(mHwc, 1); - } - } - return (status_t)err; + return (status_t)hwcBlank(mHwc, 0, 1); } return NO_ERROR; } status_t HWComposer::acquire() const { if (mHwc) { - if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { - if (mHwc->methods && mHwc->methods->blank) { - int err = mHwc->methods->blank(mHwc, 0); - return (status_t)err; - } - } + return (status_t)hwcBlank(mHwc, 0, 0); } - return NO_ERROR; } status_t HWComposer::disable() { if (mHwc) { - free(mList); - mList = NULL; - int err = mHwc->prepare(mHwc, NULL); + hwcNumHwLayers(mHwc, mLists[0]) = 0; + int err = hwcPrepare(mHwc, 1, mLists); return (status_t)err; } return NO_ERROR; } size_t HWComposer::getNumLayers() const { - return mList ? mList->numHwLayers : 0; + return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0; } /* @@ -529,13 +612,13 @@ public: * returns an iterator initialized at a given index in the layer list */ HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) { - if (!mList || index > mList->numHwLayers) { + if (index > hwcNumHwLayers(mHwc, mLists[0])) return LayerListIterator(); - } if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { - return LayerListIterator(new HWCLayerVersion1(mList->hwLayers), index); + return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers), + index); } else { - hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList; + hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index); } } @@ -554,26 +637,26 @@ HWComposer::LayerListIterator HWComposer::end() { return getLayerIterator(getNumLayers()); } - - void HWComposer::dump(String8& result, char* buffer, size_t SIZE, const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { - if (mHwc && mList) { + if (mHwc) { + hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; + result.append("Hardware Composer state:\n"); result.appendFormat(" mDebugForceFakeVSync=%d\n", mDebugForceFakeVSync); result.appendFormat(" numHwLayers=%u, flags=%08x\n", - mList->numHwLayers, mList->flags); + hwcNumHwLayers(mHwc, mLists[0]), hwcFlags(mHwc, mLists[0])); result.append( " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] - for (size_t i=0 ; i<mList->numHwLayers ; i++) { + for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) { hwc_layer_1_t l; if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { - l = mList->hwLayers[i]; + l = mLists[0]->hwLayers[i]; } else { - hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList; + hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; *(hwc_layer_t*)&l = list0->hwLayers[i]; l.acquireFenceFd = l.releaseFenceFd = -1; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 607cbae8f6..112e12067e 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -34,7 +34,7 @@ extern "C" int clock_nanosleep(clockid_t clock_id, int flags, struct timespec *remain); struct hwc_composer_device_1; -struct hwc_layer_list_1; +struct hwc_display_contents_1; struct hwc_procs; namespace android { @@ -215,6 +215,8 @@ public: const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; private: + enum { MAX_DISPLAYS = 1 }; + LayerListIterator getLayerIterator(size_t index); struct cb_context; @@ -228,7 +230,10 @@ private: sp<SurfaceFlinger> mFlinger; hw_module_t const* mModule; struct hwc_composer_device_1* mHwc; - struct hwc_layer_list_1* mList; + // invariant: mLists[0] != NULL iff mHwc != NULL + // TODO: decide whether mLists[i>0] should be non-NULL when display i is + // not attached/enabled. + struct hwc_display_contents_1* mLists[MAX_DISPLAYS]; size_t mCapacity; mutable size_t mNumOVLayers; mutable size_t mNumFBLayers; |