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 21namespace android { 22namespace intel { 23 24DisplayAnalyzer::DisplayAnalyzer() 25 : mInitialized(false), 26 mCachedNumDisplays(0), 27 mCachedDisplays(0), 28 mPendingEvents(), 29 mEventMutex() 30{ 31} 32 33DisplayAnalyzer::~DisplayAnalyzer() 34{ 35} 36 37bool DisplayAnalyzer::initialize() 38{ 39 mCachedNumDisplays = 0; 40 mCachedDisplays = 0; 41 mPendingEvents.clear(); 42 mInitialized = true; 43 44 return true; 45} 46 47void DisplayAnalyzer::deinitialize() 48{ 49 mPendingEvents.clear(); 50 mInitialized = false; 51} 52 53void 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 63void 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 73void DisplayAnalyzer::postEvent(Event& e) 74{ 75 Mutex::Autolock lock(mEventMutex); 76 mPendingEvents.add(e); 77} 78 79bool 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 90void 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 106void 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 115void 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 123void 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