Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1299c53 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Faked HWC for SurfaceFlinger testing"

parents 986678fc a099a24c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ cc_library_shared {
        "IProducerListener.cpp",
        "ISurfaceComposer.cpp",
        "ISurfaceComposerClient.cpp",
        "LayerDebugInfo.cpp",
        "LayerState.cpp",
        "OccupancyTracker.cpp",
        "StreamSplitter.cpp",
+42 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerDebugInfo.h>

#include <private/gui/LayerState.h>

@@ -469,6 +470,36 @@ public:
        return result;
    }

    virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const
    {
        if (!outLayers) {
            return UNEXPECTED_NULL;
        }

        Parcel data, reply;

        status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        if (err != NO_ERROR) {
            return err;
        }

        err = remote()->transact(BnSurfaceComposer::GET_LAYER_DEBUG_INFO, data, &reply);
        if (err != NO_ERROR) {
            return err;
        }

        int32_t result = 0;
        err = reply.readInt32(&result);
        if (err != NO_ERROR) {
            return err;
        }
        if (result != NO_ERROR) {
            return result;
        }

        outLayers->clear();
        return reply.readParcelableVector(outLayers);
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this
@@ -763,6 +794,17 @@ status_t BnSurfaceComposer::onTransact(
            }
            return injectVSync(when);
        }
        case GET_LAYER_DEBUG_INFO: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            std::vector<LayerDebugInfo> outLayers;
            status_t result = getLayerDebugInfo(&outLayers);
            reply->writeInt32(result);
            if (result == NO_ERROR)
            {
                result = reply->writeParcelableVector(outLayers);
            }
            return result;
        }
        default: {
            return BBinder::onTransact(code, data, reply, flags);
        }
+136 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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 <gui/LayerDebugInfo.h>

#include <ui/DebugUtils.h>

#include <binder/Parcel.h>

#include <utils/String8.h>

using namespace android;

#define RETURN_ON_ERROR(X) do {status_t res = (X); if (res != NO_ERROR) return res;} while(false)

namespace android {

status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const {
    RETURN_ON_ERROR(parcel->writeCString(mName.c_str()));
    RETURN_ON_ERROR(parcel->writeCString(mParentName.c_str()));
    RETURN_ON_ERROR(parcel->writeCString(mType.c_str()));
    RETURN_ON_ERROR(parcel->write(mTransparentRegion));
    RETURN_ON_ERROR(parcel->write(mVisibleRegion));
    RETURN_ON_ERROR(parcel->write(mSurfaceDamageRegion));
    RETURN_ON_ERROR(parcel->writeUint32(mLayerStack));
    RETURN_ON_ERROR(parcel->writeFloat(mX));
    RETURN_ON_ERROR(parcel->writeFloat(mY));
    RETURN_ON_ERROR(parcel->writeUint32(mZ));
    RETURN_ON_ERROR(parcel->writeInt32(mWidth));
    RETURN_ON_ERROR(parcel->writeInt32(mHeight));
    RETURN_ON_ERROR(parcel->write(mCrop));
    RETURN_ON_ERROR(parcel->write(mFinalCrop));
    RETURN_ON_ERROR(parcel->writeFloat(mAlpha));
    RETURN_ON_ERROR(parcel->writeUint32(mFlags));
    RETURN_ON_ERROR(parcel->writeInt32(mPixelFormat));
    RETURN_ON_ERROR(parcel->writeUint32(static_cast<uint32_t>(mDataSpace)));
    for (size_t index = 0; index < 4; index++) {
        RETURN_ON_ERROR(parcel->writeFloat(mMatrix[index / 2][index % 2]));
    }
    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferWidth));
    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferHeight));
    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferStride));
    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferFormat));
    RETURN_ON_ERROR(parcel->writeInt32(mNumQueuedFrames));
    RETURN_ON_ERROR(parcel->writeBool(mRefreshPending));
    RETURN_ON_ERROR(parcel->writeBool(mIsOpaque));
    RETURN_ON_ERROR(parcel->writeBool(mContentDirty));
    return NO_ERROR;
}

status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) {
    mName = parcel->readCString();
    RETURN_ON_ERROR(parcel->errorCheck());
    mParentName = parcel->readCString();
    RETURN_ON_ERROR(parcel->errorCheck());
    mType = parcel->readCString();
    RETURN_ON_ERROR(parcel->errorCheck());
    RETURN_ON_ERROR(parcel->read(mTransparentRegion));
    RETURN_ON_ERROR(parcel->read(mVisibleRegion));
    RETURN_ON_ERROR(parcel->read(mSurfaceDamageRegion));
    RETURN_ON_ERROR(parcel->readUint32(&mLayerStack));
    RETURN_ON_ERROR(parcel->readFloat(&mX));
    RETURN_ON_ERROR(parcel->readFloat(&mY));
    RETURN_ON_ERROR(parcel->readUint32(&mZ));
    RETURN_ON_ERROR(parcel->readInt32(&mWidth));
    RETURN_ON_ERROR(parcel->readInt32(&mHeight));
    RETURN_ON_ERROR(parcel->read(mCrop));
    RETURN_ON_ERROR(parcel->read(mFinalCrop));
    RETURN_ON_ERROR(parcel->readFloat(&mAlpha));
    RETURN_ON_ERROR(parcel->readUint32(&mFlags));
    RETURN_ON_ERROR(parcel->readInt32(&mPixelFormat));
    // \todo [2017-07-25 kraita]: Static casting mDataSpace pointer to an uint32 does work. Better ways?
    mDataSpace = static_cast<android_dataspace>(parcel->readUint32());
    RETURN_ON_ERROR(parcel->errorCheck());
    for (size_t index = 0; index < 4; index++) {
        RETURN_ON_ERROR(parcel->readFloat(&mMatrix[index / 2][index % 2]));
    }
    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferWidth));
    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferHeight));
    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferStride));
    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferFormat));
    RETURN_ON_ERROR(parcel->readInt32(&mNumQueuedFrames));
    RETURN_ON_ERROR(parcel->readBool(&mRefreshPending));
    RETURN_ON_ERROR(parcel->readBool(&mIsOpaque));
    RETURN_ON_ERROR(parcel->readBool(&mContentDirty));
    return NO_ERROR;
}

std::string to_string(const LayerDebugInfo& info) {
    String8 result;

    result.appendFormat("+ %s (%s)\n", info.mType.c_str(), info.mName.c_str());
    info.mTransparentRegion.dump(result, "TransparentRegion");
    info.mVisibleRegion.dump(result, "VisibleRegion");
    info.mSurfaceDamageRegion.dump(result, "SurfaceDamageRegion");

    result.appendFormat("      layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ",
            info.mLayerStack, info.mZ, static_cast<double>(info.mX), static_cast<double>(info.mY),
            info.mWidth, info.mHeight);

    result.appendFormat("crop=%s, finalCrop=%s, ",
            to_string(info.mCrop).c_str(), to_string(info.mFinalCrop).c_str());
    result.appendFormat("isOpaque=%1d, invalidate=%1d, ", info.mIsOpaque, info.mContentDirty);
    result.appendFormat("dataspace=%s, ", dataspaceDetails(info.mDataSpace).c_str());
    result.appendFormat("pixelformat=%s, ", decodePixelFormat(info.mPixelFormat).c_str());
    result.appendFormat("alpha=%.3f, flags=0x%08x, ",
            static_cast<double>(info.mAlpha), info.mFlags);
    result.appendFormat("tr=[%.2f, %.2f][%.2f, %.2f]",
            static_cast<double>(info.mMatrix[0][0]), static_cast<double>(info.mMatrix[0][1]),
            static_cast<double>(info.mMatrix[1][0]), static_cast<double>(info.mMatrix[1][1]));
    result.append("\n");
    result.appendFormat("      parent=%s\n", info.mParentName.c_str());
    result.appendFormat("      activeBuffer=[%4ux%4u:%4u,%s],",
            info.mActiveBufferWidth, info.mActiveBufferHeight,
            info.mActiveBufferStride,
            decodePixelFormat(info.mActiveBufferFormat).c_str());
    result.appendFormat(" queued-frames=%d, mRefreshPending=%d",
            info.mNumQueuedFrames, info.mRefreshPending);
    result.append("\n");
    return std::string(result.c_str());
}

} // android
+8 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ struct ComposerState;
struct DisplayState;
struct DisplayInfo;
struct DisplayStatInfo;
class LayerDebugInfo;
class HdrCapabilities;
class IDisplayEventConnection;
class IGraphicBufferProducer;
@@ -195,6 +196,12 @@ public:
    virtual status_t enableVSyncInjections(bool enable) = 0;

    virtual status_t injectVSync(nsecs_t when) = 0;

    /* Gets the list of active layers in Z order for debugging purposes
     *
     * Requires the ACCESS_SURFACE_FLINGER permission.
     */
    virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const = 0;
};

// ----------------------------------------------------------------------------
@@ -229,6 +236,7 @@ public:
        SET_ACTIVE_COLOR_MODE,
        ENABLE_VSYNC_INJECTIONS,
        INJECT_VSYNC,
        GET_LAYER_DEBUG_INFO,
        CREATE_SCOPED_CONNECTION
    };

+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <binder/Parcelable.h>

#include <ui/PixelFormat.h>
#include <ui/Region.h>

#include <string>

namespace android {

/* Class for transporting debug info from SurfaceFlinger to authorized
 * recipients.  The class is intended to be a data container. There are
 * no getters or setters.
 */
class LayerDebugInfo : public Parcelable {
public:
    LayerDebugInfo() = default;
    LayerDebugInfo(const LayerDebugInfo&) = default;
    virtual ~LayerDebugInfo() = default;

    virtual status_t writeToParcel(Parcel* parcel) const;
    virtual status_t readFromParcel(const Parcel* parcel);

    std::string mName = std::string("NOT FILLED");
    std::string mParentName = std::string("NOT FILLED");
    std::string mType = std::string("NOT FILLED");
    Region mTransparentRegion = Region::INVALID_REGION;
    Region mVisibleRegion = Region::INVALID_REGION;
    Region mSurfaceDamageRegion = Region::INVALID_REGION;
    uint32_t mLayerStack = 0;
    float mX = 0.f;
    float mY = 0.f;
    uint32_t mZ = 0 ;
    int32_t mWidth = -1;
    int32_t mHeight = -1;
    Rect mCrop = Rect::INVALID_RECT;
    Rect mFinalCrop = Rect::INVALID_RECT;
    float mAlpha = 0.f;
    uint32_t mFlags = 0;
    PixelFormat mPixelFormat = PIXEL_FORMAT_NONE;
    android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
    // Row-major transform matrix (SurfaceControl::setMatrix())
    float mMatrix[2][2] = {{0.f, 0.f}, {0.f, 0.f}};
    int32_t mActiveBufferWidth = -1;
    int32_t mActiveBufferHeight = -1;
    int32_t mActiveBufferStride = 0;
    PixelFormat mActiveBufferFormat = PIXEL_FORMAT_NONE;
    int32_t mNumQueuedFrames = -1;
    bool mRefreshPending = false;
    bool mIsOpaque = false;
    bool mContentDirty = false;
};

std::string to_string(const LayerDebugInfo& info);

} // namespace android
Loading