02 最简单的SurfaceFlinger应用程序

本文详细介绍了如何在Android中使用SurfaceFlinger创建Surface,设置属性,填充图像数据并进行推送,通过SurfaceTestDemo展示了从创建Surface到推送动态变化图片的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用SurfaceFlinger送图,可以简单的按照如下几个步骤:

  1. 创建SurfaceComposerClient   --->具体过程见《构造surfaceComposerClient》
  2. 获取要显示的屏幕,这里获取的是主屏SurfaceComposerClient::getInternalDisplayToken
  3. 获取屏幕大小 SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
  4. 创建SurfaceControl
  5. 设置surface属性;setLayer,setPosition
  6. 创建surface
  7. 分配并map buffer;surface->lock
  8. 向buffer里填充图像数据
  9. 推图 surface->unlockAndPost()

源码如下,会在屏幕中间显示一个大小200x200,颜色rgb依次循环的方块。

#define LOG_TAG "SurfaceTestDemo"

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <hardware/gralloc.h>
#include <ui/GraphicBuffer.h>
#include <utils/Log.h>
#include <gui/Surface.h>
#include <gui/SurfaceControl.h>
#include <gui/ISurfaceComposerClient.h>
#include <gui/SurfaceComposerClient.h>

#include <system/window.h>
#include <utils/RefBase.h>
using namespace android;

void fillRGBA8Buffer(uint8_t* img, int width, int height, int stride, int r, int g, int b) {
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            uint8_t* pixel = img + (4 * (y*stride + x));
            pixel[0] = r;
            pixel[1] = g;
            pixel[2] = b;
            pixel[3] = 255;
        }
    }
}

int SurfaceTest() {
    status_t err = NO_ERROR;
    int countFrame = 0;
    ANativeWindow_Buffer nativeBuffer;

    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    sp<SurfaceComposerClient> surfaceComposerClient = new SurfaceComposerClient();
    err = surfaceComposerClient->initCheck();
    if (err != NO_ERROR) {
        ALOGD("SurfaceComposerClient::initCheck error: %#x\n", err);
        return -1;
    }

    // Get main display parameters.
    sp<IBinder> displayToken = SurfaceComposerClient::getInternalDisplayToken();
    if (displayToken == nullptr)
        return -1;

    ui::DisplayMode displayMode;
    const status_t error =
            SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode);
    if (error != NO_ERROR)
        return -1;

    ui::Size resolution(200,200);
    // create the surface
    sp<SurfaceControl> surfaceControl = surfaceComposerClient->createSurface(String8("SurfaceTestDemo"), resolution.getWidth(), 
                                                                             resolution.getHeight(), PIXEL_FORMAT_RGBA_8888,
                                                                             ISurfaceComposerClient::eFXSurfaceBufferState,
                                                                             /*parent*/ nullptr);

    SurfaceComposerClient::Transaction{}
            .setLayer(surfaceControl, std::numeric_limits<int32_t>::max())
            .setPosition(surfaceControl, (displayMode.resolution.getWidth() - 200) / 2,
                (displayMode.resolution.getHeight() - 200) / 2)
            .show(surfaceControl)
            .apply();

    int mWidth = resolution.getWidth();
    int mHeight = resolution.getHeight();
    sp<Surface> surface = surfaceControl->getSurface();

    while(1) {
        countFrame = (countFrame+1)%3;
        surface->lock(&nativeBuffer, NULL);
        fillRGBA8Buffer((uint8_t *)nativeBuffer.bits, mWidth, mHeight, nativeBuffer.stride,
                        countFrame == 0 ? 255 : 0,
                        countFrame == 1 ? 255 : 0,
                        countFrame == 2 ? 255 : 0);
        surface->unlockAndPost();
        sleep(1);
    }

    return err;
}

int main() {
    SurfaceTest();
    return 0;
}

后面会根据这个简单的应用程序来一步一步剖析SurfaceFlinger的工作机制。

敬请期待。

创作不易,欢迎点赞收藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值