C++程序  |  142行  |  3.36 KB

/*
// 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