C++程序  |  249行  |  5.37 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 <DisplayQuery.h>
#include <common/observers/SoftVsyncObserver.h>
#include <DummyDevice.h>

namespace android {
namespace intel {
DummyDevice::DummyDevice(uint32_t disp, Hwcomposer& hwc)
    : mInitialized(false),
      mConnected(false),
      mBlank(false),
      mDisp(disp),
      mHwc(hwc),
      mVsyncObserver(NULL),
      mName("Dummy")
{
    CTRACE();
}

DummyDevice::~DummyDevice()
{
    WARN_IF_NOT_DEINIT();
}

bool DummyDevice::prePrepare(hwc_display_contents_1_t *display)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (!display) {
        return true;
    }

    // nothing need to do for dummy display
    return true;
}

bool DummyDevice::prepare(hwc_display_contents_1_t *display)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (!display || mDisp >= DEVICE_VIRTUAL) {
        return true;
    }

    // skip all layers composition on dummy display
    if (display->flags & HWC_GEOMETRY_CHANGED) {
        for (size_t i=0; i < display->numHwLayers-1; i++) {
            hwc_layer_1 * player = &display->hwLayers[i];
            player->compositionType = HWC_OVERLAY;
            player->flags &= ~HWC_SKIP_LAYER;
        }
    }

    return true;
}

bool DummyDevice::commit(hwc_display_contents_1_t *display, IDisplayContext *context)
{
    RETURN_FALSE_IF_NOT_INIT();

    if (!display || !context)
        return true;

    // nothing need to do for dummy display
    return true;
}

bool DummyDevice::vsyncControl(bool enabled)
{
    RETURN_FALSE_IF_NOT_INIT();
    return mVsyncObserver->control(enabled);
}

bool DummyDevice::blank(bool blank)
{
    RETURN_FALSE_IF_NOT_INIT();

    mBlank = blank;

    return true;
}

bool DummyDevice::getDisplaySize(int *width, int *height)
{
    RETURN_FALSE_IF_NOT_INIT();
    if (!width || !height) {
        ELOGTRACE("invalid parameters");
        return false;
    }

    // TODO: make this platform specifc
    *width = 1280;//720;
    *height = 720;//1280;
    return true;
}

bool DummyDevice::getDisplayConfigs(uint32_t *configs,
                                         size_t *numConfigs)
{
    RETURN_FALSE_IF_NOT_INIT();
    if (!configs || !numConfigs) {
        ELOGTRACE("invalid parameters");
        return false;
    }

    if (!mConnected) {
        ILOGTRACE("dummy device is not connected");
        return false;
    }

    *configs = 0;
    *numConfigs = 1;

    return true;
}

bool DummyDevice::getDisplayAttributes(uint32_t configs,
                                            const uint32_t *attributes,
                                            int32_t *values)
{
    RETURN_FALSE_IF_NOT_INIT();

    if ((configs > 0) || !attributes || !values) {
        ELOGTRACE("invalid parameters");
        return false;
    }

    if (!mConnected) {
        ILOGTRACE("dummy device is not connected");
        return false;
    }

    int i = 0;
    while (attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE) {
        switch (attributes[i]) {
        case HWC_DISPLAY_VSYNC_PERIOD:
            values[i] = 1e9 / 60;
            break;
        case HWC_DISPLAY_WIDTH:
            values[i] = 1280;
            break;
        case HWC_DISPLAY_HEIGHT:
            values[i] = 720;
            break;
        case HWC_DISPLAY_DPI_X:
            values[i] = 0;
            break;
        case HWC_DISPLAY_DPI_Y:
            values[i] = 0;
            break;
        default:
            ELOGTRACE("unknown attribute %d", attributes[i]);
            break;
        }
        i++;
    }

    return true;
}

bool DummyDevice::compositionComplete()
{
    RETURN_FALSE_IF_NOT_INIT();
    return true;
}

bool DummyDevice::initialize()
{
    mInitialized = true;

    mVsyncObserver = new SoftVsyncObserver(*this);
    if (!mVsyncObserver || !mVsyncObserver->initialize()) {
        DEINIT_AND_RETURN_FALSE("Failed to create Soft Vsync Observer");
        mInitialized = false;
    }

    return mInitialized;
}

bool DummyDevice::isConnected() const
{
    return mConnected;
}

const char* DummyDevice::getName() const
{
    return "Dummy";
}

int DummyDevice::getType() const
{
    return mDisp;
}

void DummyDevice::onVsync(int64_t timestamp)
{
    if (!mConnected)
        return;

    mHwc.vsync(mDisp, timestamp);
}

void DummyDevice::dump(Dump& d)
{
    d.append("-------------------------------------------------------------\n");
    d.append("Device Name: %s (%s)\n", mName,
            mConnected ? "connected" : "disconnected");
}

void DummyDevice::deinitialize()
{
    DEINIT_AND_DELETE_OBJ(mVsyncObserver);
    mInitialized = false;
}

bool DummyDevice::setPowerMode(int /*mode*/)
{
    return true;
}

int DummyDevice::getActiveConfig()
{
    return 0;
}

bool DummyDevice::setActiveConfig(int /*index*/)
{
    return false;
}

} // namespace intel
} // namespace android