diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp index bb305dcaf..ab5277eec 100644 --- a/opengl/tests/hwc/hwcColorEquiv.cpp +++ b/opengl/tests/hwc/hwcColorEquiv.cpp @@ -124,7 +124,7 @@ const float defaultEndDelay = 2.0; // Default delay after rendering graphics // Globals static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_RARELY; -static hwc_composer_device_t *hwcDevice; +static hwc_composer_device_1_t *hwcDevice; static EGLDisplay dpy; static EGLSurface surface; static EGLint width, height; @@ -344,16 +344,16 @@ main(int argc, char *argv[]) hwcTestFillColorHBlend(equivFrame.get(), refFormat->format, startRefColor, endRefColor); - hwc_layer_list_t *list; - size_t size = sizeof(hwc_layer_list) + numFrames * sizeof(hwc_layer_t); - if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) { + 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) { testPrintE("Allocate list failed"); exit(11); } list->flags = HWC_GEOMETRY_CHANGED; list->numHwLayers = numFrames; - hwc_layer_t *layer = &list->hwLayers[0]; + hwc_layer_1_t *layer = &list->hwLayers[0]; layer->handle = refFrame->handle; layer->blending = HWC_BLENDING_NONE; layer->sourceCrop.left = 0; diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp index efa646cc8..d4873d8dc 100644 --- a/opengl/tests/hwc/hwcCommit.cpp +++ b/opengl/tests/hwc/hwcCommit.cpp @@ -230,7 +230,7 @@ private: // Globals static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_RARELY; -static hwc_composer_device_t *hwcDevice; +static hwc_composer_device_1_t *hwcDevice; static EGLDisplay dpy; static EGLSurface surface; static EGLint width, height; @@ -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& rectList) { - hwc_layer_list_t *hwcList; + hwc_layer_list_1_t *hwcList; list > buffers; hwcList = hwcTestCreateLayerList(rectList.size()); @@ -1406,7 +1406,7 @@ uint32_t numOverlays(list& rectList) exit(30); } - hwc_layer_t *layer = &hwcList->hwLayers[0]; + hwc_layer_1_t *layer = &hwcList->hwLayers[0]; for (std::list::iterator it = rectList.begin(); it != rectList.end(); ++it, ++layer) { // Allocate the texture for the source frame diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp index 906c1696f..e2f003980 100644 --- a/opengl/tests/hwc/hwcRects.cpp +++ b/opengl/tests/hwc/hwcRects.cpp @@ -165,7 +165,7 @@ public: list rectangle; static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_RARELY; -static hwc_composer_device_t *hwcDevice; +static hwc_composer_device_1_t *hwcDevice; static EGLDisplay dpy; static EGLSurface surface; static EGLint width, height; @@ -307,14 +307,14 @@ main(int argc, char *argv[]) } // Create list of frames - hwc_layer_list_t *list; + hwc_layer_list_1_t *list; list = hwcTestCreateLayerList(rectangle.size()); if (list == NULL) { testPrintE("hwcTestCreateLayerList failed"); exit(5); } - hwc_layer_t *layer = &list->hwLayers[0]; + hwc_layer_1_t *layer = &list->hwLayers[0]; for (std::list::iterator it = rectangle.begin(); it != rectangle.end(); ++it, ++layer) { layer->handle = it->texture->handle; diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp index b02a424a5..ccc732843 100644 --- a/opengl/tests/hwc/hwcStress.cpp +++ b/opengl/tests/hwc/hwcStress.cpp @@ -192,7 +192,7 @@ const vector vecTransformFlags(transformFlags, // File scope globals static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_RARELY; -static hwc_composer_device_t *hwcDevice; +static hwc_composer_device_1_t *hwcDevice; static EGLDisplay dpy; static EGLSurface surface; static EGLint width, height; @@ -409,7 +409,7 @@ main(int argc, char *argv[]) // generated for this pass. srand48(pass); - hwc_layer_list_t *list; + hwc_layer_list_1_t *list; list = hwcTestCreateLayerList(testRandMod(frames.size()) + 1); if (list == NULL) { testPrintE("hwcTestCreateLayerList failed"); @@ -428,7 +428,7 @@ main(int argc, char *argv[]) for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { unsigned int idx = testRandMod(selectedFrames[n1].size()); sp gBuf = selectedFrames[n1][idx]; - hwc_layer_t *layer = &list->hwLayers[n1]; + hwc_layer_1_t *layer = &list->hwLayers[n1]; layer->handle = gBuf->handle; layer->blending = blendingOps[testRandMod(NUMA(blendingOps))]; @@ -497,7 +497,7 @@ main(int argc, char *argv[]) for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { unsigned int idx = testRandMod(selectedFrames[n1].size()); sp gBuf = selectedFrames[n1][idx]; - hwc_layer_t *layer = &list->hwLayers[n1]; + hwc_layer_1_t *layer = &list->hwLayers[n1]; layer->handle = (native_handle_t *) gBuf->handle; } diff --git a/opengl/tests/hwc/hwcTestLib.cpp b/opengl/tests/hwc/hwcTestLib.cpp index 28e0c3f37..c6dbe9dcb 100644 --- a/opengl/tests/hwc/hwcTestLib.cpp +++ b/opengl/tests/hwc/hwcTestLib.cpp @@ -134,7 +134,7 @@ void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface, } // Open Hardware Composer Device -void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr) +void hwcTestOpenHwc(hwc_composer_device_1_t **hwcDevicePtr) { int rv; hw_module_t const *hwcModule; @@ -145,7 +145,7 @@ void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr) perror(NULL); exit(77); } - if ((rv = hwc_open(hwcModule, hwcDevicePtr)) != 0) { + if ((rv = hwc_open_1(hwcModule, hwcDevicePtr)) != 0) { testPrintE("hwc_open failed, rv: %i", rv); errno = -rv; perror(NULL); @@ -399,12 +399,12 @@ const char *hwcTestGraphicFormat2str(uint32_t format) * Dynamically creates layer list with numLayers worth * of hwLayers entries. */ -hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers) +hwc_layer_list_1_t *hwcTestCreateLayerList(size_t numLayers) { - hwc_layer_list_t *list; + hwc_layer_list_1_t *list; - size_t size = sizeof(hwc_layer_list) + numLayers * sizeof(hwc_layer_t); - if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) { + 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) { return NULL; } list->flags = HWC_GEOMETRY_CHANGED; @@ -417,13 +417,13 @@ hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers) * hwcTestFreeLayerList * Frees memory previous allocated via hwcTestCreateLayerList(). */ -void hwcTestFreeLayerList(hwc_layer_list_t *list) +void hwcTestFreeLayerList(hwc_layer_list_1_t *list) { free(list); } // Display the settings of the layer list pointed to by list -void hwcTestDisplayList(hwc_layer_list_t *list) +void hwcTestDisplayList(hwc_layer_list_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_t *list) * Displays the portions of a list that are meant to be modified by * a prepare call. */ -void hwcTestDisplayListPrepareModifiable(hwc_layer_list_t *list) +void hwcTestDisplayListPrepareModifiable(hwc_layer_list_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_t *list) * * Displays the handles of all the graphic buffers in the list. */ -void hwcTestDisplayListHandles(hwc_layer_list_t *list) +void hwcTestDisplayListHandles(hwc_layer_list_1_t *list) { const unsigned int maxLayersPerLine = 6; diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h index b0c301249..db3f5c12f 100644 --- a/opengl/tests/hwc/hwcTestLib.h +++ b/opengl/tests/hwc/hwcTestLib.h @@ -107,17 +107,17 @@ class HwcTestDim { // Function Prototypes void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface, EGLint *width, EGLint *height); -void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr); +void hwcTestOpenHwc(hwc_composer_device_1_t **hwcDevicePtr); const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc); const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id); const char *hwcTestGraphicFormat2str(uint32_t format); std::string hwcTestRect2str(const struct hwc_rect& rect); -hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers); -void hwcTestFreeLayerList(hwc_layer_list_t *list); -void hwcTestDisplayList(hwc_layer_list_t *list); -void hwcTestDisplayListPrepareModifiable(hwc_layer_list_t *list); -void hwcTestDisplayListHandles(hwc_layer_list_t *list); +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); 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 ce63ee719..385be63b5 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -16,6 +16,9 @@ #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 + #include #include #include @@ -41,6 +44,45 @@ #include "SurfaceFlinger.h" 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. + +#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 +// these as well. +typedef hwc_layer_1_t hwc_layer_t; +typedef hwc_layer_list_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! +static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) { + if (HWC_REMOVE_DEPRECATED_VERSIONS && + version <= HWC_DEVICE_API_VERSION_1_0) { + return true; + } else { + return hwc->common.version >= version; + } +} + +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); + } else { + return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t); + } +} + // --------------------------------------------------------------------------- struct HWComposer::cb_context { @@ -77,10 +119,20 @@ HWComposer::HWComposer( int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); if (err == 0) { - err = hwc_open(mModule, &mHwc); + err = hwc_open_1(mModule, &mHwc); ALOGE_IF(err, "%s device failed to initialize (%s)", HWC_HARDWARE_COMPOSER, strerror(-err)); if (err == 0) { + if (HWC_REMOVE_DEPRECATED_VERSIONS && + mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) { + ALOGE("%s device version %#x too old, will not be used", + HWC_HARDWARE_COMPOSER, mHwc->common.version); + hwc_close_1(mHwc); + mHwc = NULL; + } + } + + if (mHwc) { if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; @@ -88,7 +140,7 @@ HWComposer::HWComposer( mHwc->registerProcs(mHwc, &mCBContext->procs); memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); } - if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_3)) { if (mDebugForceFakeVSync) { // make sure to turn h/w vsync off in "fake vsync" mode mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); @@ -114,7 +166,7 @@ HWComposer::~HWComposer() { mVSyncThread->requestExitAndWait(); } if (mHwc) { - hwc_close(mHwc); + hwc_close_1(mHwc); } delete mCBContext; } @@ -166,8 +218,8 @@ status_t HWComposer::createWorkList(size_t numLayers) { if (mHwc) { if (!mList || mCapacity < numLayers) { free(mList); - size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); - mList = (hwc_layer_list_t*)malloc(size); + size_t size = sizeofHwcLayerList(mHwc, numLayers); + mList = (hwc_layer_list_1_t*)malloc(size); mCapacity = numLayers; } mList->flags = HWC_GEOMETRY_CHANGED; @@ -183,11 +235,19 @@ status_t HWComposer::prepare() const { size_t numFBLayers = 0; size_t count = mList->numHwLayers; for (size_t i=0 ; ihwLayers[i]); - if (l.flags & HWC_SKIP_LAYER) { - l.compositionType = HWC_FRAMEBUFFER; + hwc_layer_1_t* l = NULL; + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + l = &mList->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]; + l = (hwc_layer_1_t*)layer; } - switch (l.compositionType) { + if (l->flags & HWC_SKIP_LAYER) { + l->compositionType = HWC_FRAMEBUFFER; + } + switch (l->compositionType) { case HWC_OVERLAY: numOVLayers++; break; @@ -222,7 +282,7 @@ status_t HWComposer::commit() const { status_t HWComposer::release() const { if (mHwc) { - if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { + 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); @@ -270,14 +330,15 @@ 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 HWCLayerVersion03 : public Iterable { +class HWCLayerVersion0 : public Iterable { public: - HWCLayerVersion03(hwc_layer_t* layer) - : Iterable(layer) { } + HWCLayerVersion0(hwc_layer_t* layer) + : Iterable(layer) { } virtual int32_t getCompositionType() const { return getLayer()->compositionType; @@ -329,6 +390,69 @@ public: } } }; +// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS + +/* + * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0. + * This implements the HWCLayer side of HWCIterableLayer. + */ +class HWCLayerVersion1 : public Iterable { +public: + HWCLayerVersion1(hwc_layer_1_t* layer) + : Iterable(layer) { } + + virtual int32_t getCompositionType() const { + return getLayer()->compositionType; + } + virtual uint32_t getHints() const { + return getLayer()->hints; + } + + virtual void setDefaultState() { + getLayer()->compositionType = HWC_FRAMEBUFFER; + getLayer()->hints = 0; + getLayer()->flags = HWC_SKIP_LAYER; + getLayer()->transform = 0; + getLayer()->blending = HWC_BLENDING_NONE; + getLayer()->visibleRegionScreen.numRects = 0; + getLayer()->visibleRegionScreen.rects = NULL; + getLayer()->acquireFenceFd = -1; + getLayer()->releaseFenceFd = -1; + } + 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(getLayer()->displayFrame) = frame; + } + virtual void setCrop(const Rect& crop) { + reinterpret_cast(getLayer()->sourceCrop) = crop; + } + virtual void setVisibleRegionScreen(const Region& reg) { + getLayer()->visibleRegionScreen.rects = + reinterpret_cast( + reg.getArray(&getLayer()->visibleRegionScreen.numRects)); + } + virtual void setBuffer(const sp& buffer) { + if (buffer == 0 || buffer->handle == 0) { + getLayer()->compositionType = HWC_FRAMEBUFFER; + getLayer()->flags |= HWC_SKIP_LAYER; + getLayer()->handle = 0; + } else { + getLayer()->handle = buffer->handle; + } + } +}; /* * returns an iterator initialized at a given index in the layer list @@ -337,7 +461,12 @@ HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) { if (!mList || index > mList->numHwLayers) { return LayerListIterator(); } - return LayerListIterator(new HWCLayerVersion03(mList->hwLayers), index); + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + return LayerListIterator(new HWCLayerVersion1(mList->hwLayers), index); + } else { + hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList; + return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index); + } } /* @@ -369,7 +498,14 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] for (size_t i=0 ; inumHwLayers ; i++) { - const hwc_layer_t& l(mList->hwLayers[i]); + hwc_layer_1_t l; + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + l = mList->hwLayers[i]; + } else { + hwc_layer_list_t* list0 = (hwc_layer_list_t*)mList; + *(hwc_layer_t*)&l = list0->hwLayers[i]; + l.acquireFenceFd = l.releaseFenceFd = -1; + } const sp layer(visibleLayersSortedByZ[i]); int32_t format = -1; if (layer->getLayer() != NULL) { @@ -387,7 +523,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE, layer->getName().string()); } } - if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_1 && mHwc->dump) { + if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) { mHwc->dump(mHwc, buffer, SIZE); result.append(buffer); } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index cafa24712..05c6f6ddd 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -31,8 +31,8 @@ extern "C" int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *request, struct timespec *remain); -struct hwc_composer_device; -struct hwc_layer_list; +struct hwc_composer_device_1; +struct hwc_layer_list_1; struct hwc_procs; namespace android { @@ -218,21 +218,21 @@ private: inline void invalidate(); inline void vsync(int dpy, int64_t timestamp); - sp mFlinger; - hw_module_t const* mModule; - struct hwc_composer_device* mHwc; - struct hwc_layer_list* mList; - size_t mCapacity; - mutable size_t mNumOVLayers; - mutable size_t mNumFBLayers; - EGLDisplay mDpy; - EGLSurface mSur; - cb_context* mCBContext; - EventHandler& mEventHandler; - nsecs_t mRefreshPeriod; - size_t mVSyncCount; - sp mVSyncThread; - bool mDebugForceFakeVSync; + sp mFlinger; + hw_module_t const* mModule; + struct hwc_composer_device_1* mHwc; + struct hwc_layer_list_1* mList; + size_t mCapacity; + mutable size_t mNumOVLayers; + mutable size_t mNumFBLayers; + EGLDisplay mDpy; + EGLSurface mSur; + cb_context* mCBContext; + EventHandler& mEventHandler; + nsecs_t mRefreshPeriod; + size_t mVSyncCount; + sp mVSyncThread; + bool mDebugForceFakeVSync; }; // ---------------------------------------------------------------------------