1 /*
2 // Copyright (c) 2014 Intel Corporation 
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 
17 #include <common/utils/HwcTrace.h>
18 #include <Hwcomposer.h>
19 #include <common/base/DisplayAnalyzer.h>
20 
21 namespace android {
22 namespace intel {
23 
DisplayAnalyzer()24 DisplayAnalyzer::DisplayAnalyzer()
25     : mInitialized(false),
26       mCachedNumDisplays(0),
27       mCachedDisplays(0),
28       mPendingEvents(),
29       mEventMutex()
30 {
31 }
32 
~DisplayAnalyzer()33 DisplayAnalyzer::~DisplayAnalyzer()
34 {
35 }
36 
initialize()37 bool DisplayAnalyzer::initialize()
38 {
39     mCachedNumDisplays = 0;
40     mCachedDisplays = 0;
41     mPendingEvents.clear();
42     mInitialized = true;
43 
44     return true;
45 }
46 
deinitialize()47 void DisplayAnalyzer::deinitialize()
48 {
49     mPendingEvents.clear();
50     mInitialized = false;
51 }
52 
analyzeContents(size_t numDisplays,hwc_display_contents_1_t ** displays)53 void DisplayAnalyzer::analyzeContents(
54         size_t numDisplays, hwc_display_contents_1_t** displays)
55 {
56     // cache and use them only in this context during analysis
57     mCachedNumDisplays = numDisplays;
58     mCachedDisplays = displays;
59 
60     handlePendingEvents();
61 }
62 
postHotplugEvent(bool connected)63 void DisplayAnalyzer::postHotplugEvent(bool connected)
64 {
65     // handle hotplug event (vsync switch) asynchronously
66     Event e;
67     e.type = HOTPLUG_EVENT;
68     e.bValue = connected;
69     postEvent(e);
70     Hwcomposer::getInstance().invalidate();
71 }
72 
postEvent(Event & e)73 void DisplayAnalyzer::postEvent(Event& e)
74 {
75     Mutex::Autolock lock(mEventMutex);
76     mPendingEvents.add(e);
77 }
78 
getEvent(Event & e)79 bool DisplayAnalyzer::getEvent(Event& e)
80 {
81     Mutex::Autolock lock(mEventMutex);
82     if (mPendingEvents.size() == 0) {
83         return false;
84     }
85     e = mPendingEvents[0];
86     mPendingEvents.removeAt(0);
87     return true;
88 }
89 
handlePendingEvents()90 void DisplayAnalyzer::handlePendingEvents()
91 {
92     // handle one event per analysis to avoid blocking surface flinger
93     // some event may take lengthy time to process
94     Event e;
95     if (!getEvent(e)) {
96         return;
97     }
98 
99     switch (e.type) {
100     case HOTPLUG_EVENT:
101         handleHotplugEvent(e.bValue);
102         break;
103     }
104 }
105 
handleHotplugEvent(bool connected)106 void DisplayAnalyzer::handleHotplugEvent(bool connected)
107 {
108     if (connected) {
109         for (int i = 0; i < mCachedNumDisplays; i++) {
110             setCompositionType(i, HWC_FRAMEBUFFER, true);
111         }
112     }
113 }
114 
setCompositionType(hwc_display_contents_1_t * display,int type)115 void DisplayAnalyzer::setCompositionType(hwc_display_contents_1_t *display, int type)
116 {
117     for (size_t i = 0; i < display->numHwLayers - 1; i++) {
118         hwc_layer_1_t *layer = &display->hwLayers[i];
119         if (layer) layer->compositionType = type;
120     }
121 }
122 
setCompositionType(int device,int type,bool reset)123 void DisplayAnalyzer::setCompositionType(int device, int type, bool reset)
124 {
125     hwc_display_contents_1_t *content = mCachedDisplays[device];
126     if (content == NULL) {
127         ELOGTRACE("Invalid device %d", device);
128         return;
129     }
130 
131     // don't need to set geometry changed if layers are just needed to be marked
132     if (reset) {
133         content->flags |= HWC_GEOMETRY_CHANGED;
134     }
135 
136     setCompositionType(content, type);
137 }
138 
139 } // namespace intel
140 } // namespace android
141 
142