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