DisplayAnalyzer.cpp revision 0131f123eba74813aca3eaaf99cd418b6b558416
165efc253a628175c7afa95c431b746ea20052794Andy Qiu/*
265efc253a628175c7afa95c431b746ea20052794Andy Qiu * Copyright © 2012 Intel Corporation
365efc253a628175c7afa95c431b746ea20052794Andy Qiu * All rights reserved.
465efc253a628175c7afa95c431b746ea20052794Andy Qiu *
565efc253a628175c7afa95c431b746ea20052794Andy Qiu * Permission is hereby granted, free of charge, to any person obtaining a
665efc253a628175c7afa95c431b746ea20052794Andy Qiu * copy of this software and associated documentation files (the "Software"),
765efc253a628175c7afa95c431b746ea20052794Andy Qiu * to deal in the Software without restriction, including without limitation
865efc253a628175c7afa95c431b746ea20052794Andy Qiu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
965efc253a628175c7afa95c431b746ea20052794Andy Qiu * and/or sell copies of the Software, and to permit persons to whom the
1065efc253a628175c7afa95c431b746ea20052794Andy Qiu * Software is furnished to do so, subject to the following conditions:
1165efc253a628175c7afa95c431b746ea20052794Andy Qiu *
1265efc253a628175c7afa95c431b746ea20052794Andy Qiu * The above copyright notice and this permission notice (including the next
1365efc253a628175c7afa95c431b746ea20052794Andy Qiu * paragraph) shall be included in all copies or substantial portions of the
1465efc253a628175c7afa95c431b746ea20052794Andy Qiu * Software.
1565efc253a628175c7afa95c431b746ea20052794Andy Qiu *
1665efc253a628175c7afa95c431b746ea20052794Andy Qiu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1765efc253a628175c7afa95c431b746ea20052794Andy Qiu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1865efc253a628175c7afa95c431b746ea20052794Andy Qiu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1965efc253a628175c7afa95c431b746ea20052794Andy Qiu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2065efc253a628175c7afa95c431b746ea20052794Andy Qiu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2165efc253a628175c7afa95c431b746ea20052794Andy Qiu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2265efc253a628175c7afa95c431b746ea20052794Andy Qiu * IN THE SOFTWARE.
2365efc253a628175c7afa95c431b746ea20052794Andy Qiu *
2465efc253a628175c7afa95c431b746ea20052794Andy Qiu * Authors:
2565efc253a628175c7afa95c431b746ea20052794Andy Qiu *    Jackie Li <yaodong.li@intel.com>
2665efc253a628175c7afa95c431b746ea20052794Andy Qiu *
2765efc253a628175c7afa95c431b746ea20052794Andy Qiu */
2865efc253a628175c7afa95c431b746ea20052794Andy Qiu
2965efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <HwcTrace.h>
3065efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <IDisplayDevice.h>
3165efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <DisplayQuery.h>
3265efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <BufferManager.h>
3365efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <DisplayPlaneManager.h>
3465efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <Hwcomposer.h>
3565efc253a628175c7afa95c431b746ea20052794Andy Qiu#include <DisplayAnalyzer.h>
365490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu#include <cutils/properties.h>
3765efc253a628175c7afa95c431b746ea20052794Andy Qiu
3865efc253a628175c7afa95c431b746ea20052794Andy Qiu
3965efc253a628175c7afa95c431b746ea20052794Andy Qiunamespace android {
4065efc253a628175c7afa95c431b746ea20052794Andy Qiunamespace intel {
4165efc253a628175c7afa95c431b746ea20052794Andy Qiu
4265efc253a628175c7afa95c431b746ea20052794Andy QiuDisplayAnalyzer::DisplayAnalyzer()
4365efc253a628175c7afa95c431b746ea20052794Andy Qiu    : mInitialized(false),
445490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu      mEnableVideoExtendedMode(true),
45770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie      mVideoExtendedMode(false),
46d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu      mForceCloneMode(false),
47d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu      mBlankDevice(false),
48eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mVideoPlaying(false),
49eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mVideoPreparing(false),
50eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mOverlayAllowed(true),
51eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mCachedNumDisplays(0),
52eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mCachedDisplays(0),
53eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mPendingEvents(),
544ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu      mEventMutex(),
554ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu      mEventHandledCondition()
5665efc253a628175c7afa95c431b746ea20052794Andy Qiu{
5765efc253a628175c7afa95c431b746ea20052794Andy Qiu}
5865efc253a628175c7afa95c431b746ea20052794Andy Qiu
5965efc253a628175c7afa95c431b746ea20052794Andy QiuDisplayAnalyzer::~DisplayAnalyzer()
6065efc253a628175c7afa95c431b746ea20052794Andy Qiu{
6165efc253a628175c7afa95c431b746ea20052794Andy Qiu}
6265efc253a628175c7afa95c431b746ea20052794Andy Qiu
6365efc253a628175c7afa95c431b746ea20052794Andy Qiubool DisplayAnalyzer::initialize()
6465efc253a628175c7afa95c431b746ea20052794Andy Qiu{
655490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    // by default video extended mode is enabled
665490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    char prop[PROPERTY_VALUE_MAX];
675490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    if (property_get("hwc.video.extmode.enable", prop, "1") > 0) {
685490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu        mEnableVideoExtendedMode = atoi(prop) ? true : false;
695490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    }
70d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    mVideoExtendedMode = false;
71d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    mForceCloneMode = false;
72d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    mBlankDevice = false;
73eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mVideoPlaying = false;
74eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mVideoPreparing = false;
75eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mOverlayAllowed = true;
76eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCachedNumDisplays = 0;
77eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCachedDisplays = 0;
78eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mPendingEvents.clear();
7965efc253a628175c7afa95c431b746ea20052794Andy Qiu    mInitialized = true;
8065efc253a628175c7afa95c431b746ea20052794Andy Qiu    return true;
8165efc253a628175c7afa95c431b746ea20052794Andy Qiu}
8265efc253a628175c7afa95c431b746ea20052794Andy Qiu
83e2ad4c047651d4442f6a0e002290016d45e9201afu jinvoid DisplayAnalyzer::deinitialize()
8465efc253a628175c7afa95c431b746ea20052794Andy Qiu{
85eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mPendingEvents.clear();
8665efc253a628175c7afa95c431b746ea20052794Andy Qiu    mInitialized = false;
8765efc253a628175c7afa95c431b746ea20052794Andy Qiu}
8865efc253a628175c7afa95c431b746ea20052794Andy Qiu
89770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xievoid DisplayAnalyzer::analyzeContents(
90770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        size_t numDisplays, hwc_display_contents_1_t** displays)
91770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie{
92eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    // cache and use them only in this context during analysis
93eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCachedNumDisplays = numDisplays;
94eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCachedDisplays = displays;
95eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
96eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    handlePendingEvents();
97eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
98eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mBlankDevice) {
99eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        blankSecondaryDevice();
100eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
101eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
1025490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    if (mEnableVideoExtendedMode) {
1035490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu        detectVideoExtendedMode();
1045490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu        if (mVideoExtendedMode) {
1055490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu            detectTrickMode(mCachedDisplays[IDisplayDevice::DEVICE_PRIMARY]);
1065490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu        }
107770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    }
108eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
109eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCachedNumDisplays = 0;
110eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCachedDisplays = 0;
111770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie}
112770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie
113770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xievoid DisplayAnalyzer::detectTrickMode(hwc_display_contents_1_t *list)
114770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie{
115770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    if (list == NULL)
116770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        return;
117770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie
118770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    bool detected = false;
119770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    for (size_t i = 0; i < list->numHwLayers; i++) {
120770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        hwc_layer_1_t *layer = &list->hwLayers[i];
121770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        if (layer && (layer->flags & HWC_TRICK_MODE)) {
122770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie            detected = true;
123bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie            // reset the type
124bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie            layer->compositionType = HWC_FRAMEBUFFER;
125770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie            break;
126770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        }
127770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    }
128770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie
129770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    if (detected != mForceCloneMode) {
130770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        list->flags |= HWC_GEOMETRY_CHANGED;
131770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie        mForceCloneMode = detected;
132770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    }
133770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie}
134770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie
135eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::detectVideoExtendedMode()
13665efc253a628175c7afa95c431b746ea20052794Andy Qiu{
137eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!mVideoPlaying) {
138eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mVideoExtendedMode = false;
139eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mForceCloneMode = false;
140eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return;
141eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
142eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
14365efc253a628175c7afa95c431b746ea20052794Andy Qiu    bool geometryChanged = false;
14465efc253a628175c7afa95c431b746ea20052794Andy Qiu    int activeDisplays = 0;
145d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu
14665efc253a628175c7afa95c431b746ea20052794Andy Qiu    hwc_display_contents_1_t *content = NULL;
147eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    for (int i = 0; i < (int)mCachedNumDisplays; i++) {
148eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        content = mCachedDisplays[i];
14965efc253a628175c7afa95c431b746ea20052794Andy Qiu        if (content == NULL) {
15065efc253a628175c7afa95c431b746ea20052794Andy Qiu            continue;
15165efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
15265efc253a628175c7afa95c431b746ea20052794Andy Qiu        activeDisplays++;
15365efc253a628175c7afa95c431b746ea20052794Andy Qiu        if (content->flags & HWC_GEOMETRY_CHANGED) {
15465efc253a628175c7afa95c431b746ea20052794Andy Qiu            geometryChanged = true;
15565efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
15665efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
15765efc253a628175c7afa95c431b746ea20052794Andy Qiu
15865efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (activeDisplays <= 1) {
15965efc253a628175c7afa95c431b746ea20052794Andy Qiu        mVideoExtendedMode = false;
16065efc253a628175c7afa95c431b746ea20052794Andy Qiu        return;
16165efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
16265efc253a628175c7afa95c431b746ea20052794Andy Qiu
16365efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (geometryChanged == false) {
16465efc253a628175c7afa95c431b746ea20052794Andy Qiu        // use previous analysis result
16565efc253a628175c7afa95c431b746ea20052794Andy Qiu        return;
16665efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
16765efc253a628175c7afa95c431b746ea20052794Andy Qiu
16865efc253a628175c7afa95c431b746ea20052794Andy Qiu    // reset status of video extended mode
16965efc253a628175c7afa95c431b746ea20052794Andy Qiu    mVideoExtendedMode = false;
17065efc253a628175c7afa95c431b746ea20052794Andy Qiu
17165efc253a628175c7afa95c431b746ea20052794Andy Qiu    // check if there is video layer in the primary device
172eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    content = mCachedDisplays[0];
17365efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (content == NULL) {
17465efc253a628175c7afa95c431b746ea20052794Andy Qiu        return;
17565efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
17665efc253a628175c7afa95c431b746ea20052794Andy Qiu
177d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    uint32_t videoHandle = 0;
17865efc253a628175c7afa95c431b746ea20052794Andy Qiu    bool videoLayerExist = false;
17965efc253a628175c7afa95c431b746ea20052794Andy Qiu    // exclude the frame buffer target layer
18065efc253a628175c7afa95c431b746ea20052794Andy Qiu    for (int j = 0; j < (int)content->numHwLayers - 1; j++) {
18165efc253a628175c7afa95c431b746ea20052794Andy Qiu        videoLayerExist = isVideoLayer(content->hwLayers[j]);
182bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie        if (videoLayerExist) {
18365efc253a628175c7afa95c431b746ea20052794Andy Qiu            videoHandle = (uint32_t)content->hwLayers[j].handle;
18465efc253a628175c7afa95c431b746ea20052794Andy Qiu            break;
18565efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
18665efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
18765efc253a628175c7afa95c431b746ea20052794Andy Qiu
18865efc253a628175c7afa95c431b746ea20052794Andy Qiu    if (videoLayerExist == false) {
18965efc253a628175c7afa95c431b746ea20052794Andy Qiu        // no video layer is found in the primary layer
19065efc253a628175c7afa95c431b746ea20052794Andy Qiu        return;
19165efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
19265efc253a628175c7afa95c431b746ea20052794Andy Qiu
19365efc253a628175c7afa95c431b746ea20052794Andy Qiu    // check whether video layer exists in external device or virtual device
19465efc253a628175c7afa95c431b746ea20052794Andy Qiu    // TODO: video may exist in virtual device but no in external device or vice versa
19565efc253a628175c7afa95c431b746ea20052794Andy Qiu    // TODO: multiple video layers are not addressed here
196eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    for (int i = 1; i < (int)mCachedNumDisplays; i++) {
197eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        content = mCachedDisplays[i];
19865efc253a628175c7afa95c431b746ea20052794Andy Qiu        if (content == NULL) {
19965efc253a628175c7afa95c431b746ea20052794Andy Qiu            continue;
20065efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
20165efc253a628175c7afa95c431b746ea20052794Andy Qiu
20265efc253a628175c7afa95c431b746ea20052794Andy Qiu        // exclude the frame buffer target layer
20365efc253a628175c7afa95c431b746ea20052794Andy Qiu        for (int j = 0; j < (int)content->numHwLayers - 1; j++) {
20465efc253a628175c7afa95c431b746ea20052794Andy Qiu            if ((uint32_t)content->hwLayers[j].handle == videoHandle) {
20565efc253a628175c7afa95c431b746ea20052794Andy Qiu                ITRACE("video layer exists in device %d", i);
2060131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu                mVideoExtendedMode = isVideoFullScreen(i, content->hwLayers[j]);
20765efc253a628175c7afa95c431b746ea20052794Andy Qiu                return;
20865efc253a628175c7afa95c431b746ea20052794Andy Qiu            }
20965efc253a628175c7afa95c431b746ea20052794Andy Qiu        }
21065efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
21165efc253a628175c7afa95c431b746ea20052794Andy Qiu}
21265efc253a628175c7afa95c431b746ea20052794Andy Qiu
21365efc253a628175c7afa95c431b746ea20052794Andy Qiubool DisplayAnalyzer::checkVideoExtendedMode()
21465efc253a628175c7afa95c431b746ea20052794Andy Qiu{
215770346b3b6f55e10c54c8a47d4db8f8907035173Lin Xie    return mVideoExtendedMode && !mForceCloneMode;
21665efc253a628175c7afa95c431b746ea20052794Andy Qiu}
21765efc253a628175c7afa95c431b746ea20052794Andy Qiu
2185490411cb9330d4e92d59878da3693c33a948ad6Andy Qiubool DisplayAnalyzer::isVideoExtendedModeEnabled()
2195490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu{
2205490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu#if 1
2215490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    // enable it for run-time debugging purpose.
2225490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    char prop[PROPERTY_VALUE_MAX];
2235490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    if (property_get("hwc.video.extmode.enable", prop, "1") > 0) {
2245490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu        mEnableVideoExtendedMode = atoi(prop) ? true : false;
2255490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    }
2265490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    ITRACE("video extended mode enabled: %d", mEnableVideoExtendedMode);
2275490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu#endif
2285490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu
2295490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu    return mEnableVideoExtendedMode;
2305490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu}
2315490411cb9330d4e92d59878da3693c33a948ad6Andy Qiu
23265efc253a628175c7afa95c431b746ea20052794Andy Qiubool DisplayAnalyzer::isVideoLayer(hwc_layer_1_t &layer)
23365efc253a628175c7afa95c431b746ea20052794Andy Qiu{
23465efc253a628175c7afa95c431b746ea20052794Andy Qiu    bool ret = false;
23565efc253a628175c7afa95c431b746ea20052794Andy Qiu    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
236eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!layer.handle) {
237eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return false;
238eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
239eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    DataBuffer *buffer = bm->lockDataBuffer((uint32_t)layer.handle);
24065efc253a628175c7afa95c431b746ea20052794Andy Qiu     if (!buffer) {
24165efc253a628175c7afa95c431b746ea20052794Andy Qiu         ETRACE("failed to get buffer");
24265efc253a628175c7afa95c431b746ea20052794Andy Qiu     } else {
24365efc253a628175c7afa95c431b746ea20052794Andy Qiu        ret = DisplayQuery::isVideoFormat(buffer->getFormat());
244eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        bm->unlockDataBuffer(buffer);
24565efc253a628175c7afa95c431b746ea20052794Andy Qiu    }
24665efc253a628175c7afa95c431b746ea20052794Andy Qiu    return ret;
24765efc253a628175c7afa95c431b746ea20052794Andy Qiu}
24865efc253a628175c7afa95c431b746ea20052794Andy Qiu
2490131f123eba74813aca3eaaf99cd418b6b558416Andy Qiubool DisplayAnalyzer::isVideoFullScreen(int device, hwc_layer_1_t &layer)
250bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie{
2510131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    IDisplayDevice *displayDevice = Hwcomposer::getInstance().getDisplayDevice(device);
2520131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    if (!displayDevice) {
253bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie        return false;
254bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie    }
2550131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    int width = 0, height = 0;
2560131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    if (!displayDevice->getDisplaySize(&width, &height)) {
2570131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        return false;
2580131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    }
2590131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu
2600131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    ITRACE("video left %d, right %d, top %d, bottom %d, device width %d, height %d",
2610131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        layer.displayFrame.left, layer.displayFrame.right,
2620131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        layer.displayFrame.top, layer.displayFrame.bottom,
2630131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        width, height);
264bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie
265bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie    int dstW = layer.displayFrame.right - layer.displayFrame.left;
266bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie    int dstH = layer.displayFrame.bottom - layer.displayFrame.top;
2670131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    if (dstW < width - 1 &&
2680131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        dstH < height - 1) {
2690131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        ITRACE("video is not full-screen");
2700131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        return false;
271bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie    }
2720131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    int offset = layer.displayFrame.left + layer.displayFrame.right - width;
2730131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    if (offset > 1 || offset < -1) {
2740131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        ITRACE("video is not centralized in horizontal direction");
2750131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        return false;
2760131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    }
2770131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    offset = layer.displayFrame.top + layer.displayFrame.bottom - height;
2780131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    if (offset > 1 || offset < -1) {
2790131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        ITRACE("video is not centralized in vertical direction");
2800131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu        return false;
2810131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    }
2820131f123eba74813aca3eaaf99cd418b6b558416Andy Qiu    return true;
283bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie}
284bd5ed146ffeb236f3c5cc20b2ebaf6a850b54007Lin Xie
285eb726af21649d79ed720bdf329e0849270995c45Andy Qiubool DisplayAnalyzer::isVideoPlaying()
286d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu{
287eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    return mVideoPlaying;
288eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
289eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
290eb726af21649d79ed720bdf329e0849270995c45Andy Qiubool DisplayAnalyzer::isOverlayAllowed()
291eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
292eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    return mOverlayAllowed;
293eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
294eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
295eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::postHotplugEvent(bool connected)
296eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
297eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    // TODO: turn on primary display immeidately
298eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
299eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!connected) {
300eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        // enable vsync on the primary device immediately
301eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        Hwcomposer::getInstance().getVsyncManager()->resetVsyncSource();
302eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    } else {
303eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        // handle hotplug event (vsync switch) asynchronously
304eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        Event e;
305eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        e.type = HOTPLUG_EVENT;
306eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        e.connected = connected;
307eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        postEvent(e);
308eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        Hwcomposer::getInstance().invalidate();
309eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
310eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
311eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
312eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::postVideoEvent(bool preparing, bool playing)
313eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
314eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    Event e;
315eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    e.type = VIDEO_EVENT;
316eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    e.videoEvent.preparing = preparing;
317eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    e.videoEvent.playing = playing;
318eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    postEvent(e);
3194ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu    if (preparing) {
3204ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        Hwcomposer::getInstance().invalidate();
3214ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        Mutex::Autolock lock(mEventMutex);
3224ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        // ideally overlay should be disabled in the surface flinger thread, if it is not processed
3234ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        // in close to one vsync cycle (20ms)  it will be safely disabled in this thread context
3244ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        // there is no threading issue
3254ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        status_t err = mEventHandledCondition.waitRelative(mEventMutex, milliseconds(20));
3264ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        if (err == -ETIMEDOUT) {
3274ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu            WTRACE("timeout waiting for event handling");
3284ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu            Hwcomposer::getInstance().getPlaneManager()->disableOverlayPlanes();
3294ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        }
3304ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu    }
331eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
332eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
333eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::postBlankEvent(bool blank)
334eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
335eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    Event e;
336eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    e.type = BLANK_EVENT;
337eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    e.blank = blank;
338eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    postEvent(e);
339d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    Hwcomposer::getInstance().invalidate();
340d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu}
341d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu
342eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::postEvent(Event& e)
343d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu{
344eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    Mutex::Autolock lock(mEventMutex);
345eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mPendingEvents.add(e);
346eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
347eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
348eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::handlePendingEvents()
349eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
350eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    Mutex::Autolock lock(mEventMutex);
351eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mPendingEvents.size() == 0) {
352eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return;
353eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
354eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
355eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    while (mPendingEvents.size() != 0) {
356eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        Event e = mPendingEvents[0];
357eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mPendingEvents.removeAt(0);
358eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        switch (e.type) {
359eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        case HOTPLUG_EVENT:
360eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            handleHotplugEvent(e.connected);
361eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            break;
362eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        case BLANK_EVENT:
363eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            handleBlankEvent(e.blank);
364eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            break;
365eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        case VIDEO_EVENT:
366eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            handleVideoEvent(e.videoEvent.preparing, e.videoEvent.playing);
367eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            break;
368eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        }
369eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
370eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
371eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
372eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::handleHotplugEvent(bool connected)
373eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
374eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    Hwcomposer::getInstance().getVsyncManager()->resetVsyncSource();
375eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
376eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
377eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::handleBlankEvent(bool blank)
378eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
379eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mBlankDevice = blank;
380eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    // force geometry changed in the secondary device to reset layer composition type
381eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    for (int i = 0; i < (int)mCachedNumDisplays; i++) {
382eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        if (i == IDisplayDevice::DEVICE_PRIMARY) {
383eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            continue;
384eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        }
385eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        if (mCachedDisplays[i]) {
386eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            mCachedDisplays[i]->flags |= HWC_GEOMETRY_CHANGED;
387eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        }
388d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    }
389eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    blankSecondaryDevice();
390eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
391d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu
392eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::handleVideoEvent(bool preparing, bool playing)
393eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
394eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (preparing != mVideoPreparing) {
395eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        for (int i = 0; i < (int)mCachedNumDisplays; i++) {
396eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            if (mCachedDisplays[i]) {
397eb726af21649d79ed720bdf329e0849270995c45Andy Qiu                mCachedDisplays[i]->flags = HWC_GEOMETRY_CHANGED;
398eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            }
399eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        }
400eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mVideoPreparing = preparing;
401eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        // if video is in preparing stage, overlay use is temporarily not allowed to avoid
402eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        // scrambed RGB overlay if video is protected.
403eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mOverlayAllowed = !preparing;
404eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
405eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mVideoPlaying = playing;
4064ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu    if (preparing) {
4074ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        Hwcomposer::getInstance().getPlaneManager()->disableOverlayPlanes();
4084ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu        mEventHandledCondition.signal();
4094ffa9f40b823e4c99cd7a21598373969517d93a8Andy Qiu    }
410eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
411eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
412eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid DisplayAnalyzer::blankSecondaryDevice()
413eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
414d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    hwc_display_contents_1_t *content = NULL;
415d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    hwc_layer_1 *layer = NULL;
416eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    for (int i = 0; i < (int)mCachedNumDisplays; i++) {
417d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu        if (i == IDisplayDevice::DEVICE_PRIMARY) {
418d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            continue;
419d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu        }
420eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        content = mCachedDisplays[i];
421d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu        if (content == NULL) {
422d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            continue;
423d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu        }
424d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu
425d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu        for (int j = 0; j < (int)content->numHwLayers - 1; j++) {
426d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            layer = &content->hwLayers[j];
427d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            if (!layer) {
428d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu                continue;
429d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            }
430d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            if (mBlankDevice) {
431d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu                layer->hints |= HWC_HINT_CLEAR_FB;
432d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu                layer->flags &= ~HWC_SKIP_LAYER;
433d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu                layer->compositionType = HWC_OVERLAY;
434d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            } else {
435d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu                layer->hints &= ~HWC_HINT_CLEAR_FB;
436d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu                layer->compositionType = HWC_FRAMEBUFFER;
437d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu            }
438d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu        }
439d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu    }
440d4e9a8ac464ef6fde755c1a8c0902dc02a1270ecAndy Qiu}
44165efc253a628175c7afa95c431b746ea20052794Andy Qiu
44265efc253a628175c7afa95c431b746ea20052794Andy Qiu} // namespace intel
44365efc253a628175c7afa95c431b746ea20052794Andy Qiu} // namespace android
44465efc253a628175c7afa95c431b746ea20052794Andy Qiu
445