| /* |
| // Copyright (c) 2014 Intel Corporation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| */ |
| |
| #include <common/utils/HwcTrace.h> |
| #include <Hwcomposer.h> |
| #include <common/base/DisplayAnalyzer.h> |
| |
| namespace android { |
| namespace intel { |
| |
| DisplayAnalyzer::DisplayAnalyzer() |
| : mInitialized(false), |
| mCachedNumDisplays(0), |
| mCachedDisplays(0), |
| mPendingEvents(), |
| mEventMutex() |
| { |
| } |
| |
| DisplayAnalyzer::~DisplayAnalyzer() |
| { |
| } |
| |
| bool DisplayAnalyzer::initialize() |
| { |
| mCachedNumDisplays = 0; |
| mCachedDisplays = 0; |
| mPendingEvents.clear(); |
| mInitialized = true; |
| |
| return true; |
| } |
| |
| void DisplayAnalyzer::deinitialize() |
| { |
| mPendingEvents.clear(); |
| mInitialized = false; |
| } |
| |
| void DisplayAnalyzer::analyzeContents( |
| size_t numDisplays, hwc_display_contents_1_t** displays) |
| { |
| // cache and use them only in this context during analysis |
| mCachedNumDisplays = numDisplays; |
| mCachedDisplays = displays; |
| |
| handlePendingEvents(); |
| } |
| |
| void DisplayAnalyzer::postHotplugEvent(bool connected) |
| { |
| // handle hotplug event (vsync switch) asynchronously |
| Event e; |
| e.type = HOTPLUG_EVENT; |
| e.bValue = connected; |
| postEvent(e); |
| Hwcomposer::getInstance().invalidate(); |
| } |
| |
| void DisplayAnalyzer::postEvent(Event& e) |
| { |
| Mutex::Autolock lock(mEventMutex); |
| mPendingEvents.add(e); |
| } |
| |
| bool DisplayAnalyzer::getEvent(Event& e) |
| { |
| Mutex::Autolock lock(mEventMutex); |
| if (mPendingEvents.size() == 0) { |
| return false; |
| } |
| e = mPendingEvents[0]; |
| mPendingEvents.removeAt(0); |
| return true; |
| } |
| |
| void DisplayAnalyzer::handlePendingEvents() |
| { |
| // handle one event per analysis to avoid blocking surface flinger |
| // some event may take lengthy time to process |
| Event e; |
| if (!getEvent(e)) { |
| return; |
| } |
| |
| switch (e.type) { |
| case HOTPLUG_EVENT: |
| handleHotplugEvent(e.bValue); |
| break; |
| } |
| } |
| |
| void DisplayAnalyzer::handleHotplugEvent(bool connected) |
| { |
| if (connected) { |
| for (int i = 0; i < mCachedNumDisplays; i++) { |
| setCompositionType(i, HWC_FRAMEBUFFER, true); |
| } |
| } |
| } |
| |
| void DisplayAnalyzer::setCompositionType(hwc_display_contents_1_t *display, int type) |
| { |
| for (size_t i = 0; i < display->numHwLayers - 1; i++) { |
| hwc_layer_1_t *layer = &display->hwLayers[i]; |
| if (layer) layer->compositionType = type; |
| } |
| } |
| |
| void DisplayAnalyzer::setCompositionType(int device, int type, bool reset) |
| { |
| hwc_display_contents_1_t *content = mCachedDisplays[device]; |
| if (content == NULL) { |
| ELOGTRACE("Invalid device %d", device); |
| return; |
| } |
| |
| // don't need to set geometry changed if layers are just needed to be marked |
| if (reset) { |
| content->flags |= HWC_GEOMETRY_CHANGED; |
| } |
| |
| setCompositionType(content, type); |
| } |
| |
| } // namespace intel |
| } // namespace android |
| |