1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 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 24 DisplayAnalyzer::DisplayAnalyzer() 25 : mInitialized(false), 26 mCachedNumDisplays(0), 27 mCachedDisplays(0), 28 mPendingEvents(), 29 mEventMutex() 30 { 31 } 32 33 DisplayAnalyzer::~DisplayAnalyzer() 34 { 35 } 36 37 bool DisplayAnalyzer::initialize() 38 { 39 mCachedNumDisplays = 0; 40 mCachedDisplays = 0; 41 mPendingEvents.clear(); 42 mInitialized = true; 43 44 return true; 45 } 46 47 void DisplayAnalyzer::deinitialize() 48 { 49 mPendingEvents.clear(); 50 mInitialized = false; 51 } 52 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 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 73 void DisplayAnalyzer::postEvent(Event& e) 74 { 75 Mutex::Autolock lock(mEventMutex); 76 mPendingEvents.add(e); 77 } 78 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 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 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 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 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