最簡單的BufferQueue測試程序(三)

前言

前面兩篇文章《最簡單的BufferQueue測試程序(一)》《最簡單的BufferQueue測試程序(二)》演示的都是在本地同一進程中操作BufferQueue,而實際使用過程中往往會出現Producer和Consumer位於不同的進程,這時候就需要通過binder調用來實現跨進程操作BufferQueue了。

本篇將以最簡單的代碼形式,演示如何在遠程操作BufferQueue。

Android版本:8.1

參考代碼

server.cpp

#define LOG_TAG "MyTest"

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>

#include <gui/BufferQueue.h>

#include <thread>

using namespace android;

struct DummyConsumer : public BnConsumerListener {
    void onFrameAvailable(const BufferItem& /* item */) override {}
    void onBuffersReleased() override {}
    void onSidebandStreamChanged() override {}
};

int main(int argc, char** argv)
{
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);

    consumer->consumerConnect(new DummyConsumer, false);

    sp<IServiceManager> serviceManager = defaultServiceManager();
    serviceManager->addService(String16("MyProducer"), IInterface::asBinder(producer));
    serviceManager->addService(String16("MyConsumer"), IInterface::asBinder(consumer));

    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();

    return 0;
}

client.cpp

#define LOG_TAG "MyTest"

#include <binder/IServiceManager.h>

#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
#include <ui/GraphicBuffer.h>

#include <system/window.h>

using namespace android;

int main(int argc, char** argv)
{
    sp<IServiceManager> serviceManager = defaultServiceManager();
    sp<IBinder> binderProducer = serviceManager->getService(String16("MyProducer"));
    sp<IBinder> binderConsumer = serviceManager->getService(String16("MyConsumer"));
    sp<IGraphicBufferProducer> producer = interface_cast<IGraphicBufferProducer>(binderProducer);
    sp<IGraphicBufferConsumer> consumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);

    IGraphicBufferProducer::QueueBufferOutput output;
    producer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, &output);

    /****************** Producer ***********************/
    int slot;
    sp<Fence> fence;
    sp<GraphicBuffer> buffer;
    producer->dequeueBuffer(&slot, &fence, 0, 0, 0,
		    	     GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
    producer->requestBuffer(slot, &buffer);

    uint32_t* dataIn;
    buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
		 reinterpret_cast<void**>(&dataIn));
    *dataIn = 0x12345678u;
    buffer->unlock();

    IGraphicBufferProducer::QueueBufferInput input(0, false, HAL_DATASPACE_UNKNOWN, Rect(1, 1),
				    NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    producer->queueBuffer(slot, input, &output);


    /****************** Consumer ***********************/
    BufferItem item;
    consumer->acquireBuffer(&item, static_cast<nsecs_t>(0));

    uint32_t* dataOut;
    item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
		    	      reinterpret_cast<void**>(&dataOut));
    printf("data out is 0x%08x\n", *dataOut);
    item.mGraphicBuffer->unlock();

    consumer->releaseBuffer(item.mSlot, item.mFrameNumber, EGL_NO_DISPLAY,
		    	     EGL_NO_SYNC_KHR, Fence::NO_FENCE);

    return 0;
}

Android.bp

cc_test {
    name: "client",

    srcs: ["client.cpp"],

    clang: true,

    shared_libs: [
        "liblog",
        "libbinder",
        "libgui",
        "libui",
        "libutils",
    ],
}

cc_test {
    name: "server",

    srcs: ["server.cpp"],

    clang: true,

    shared_libs: [
        "liblog",
        "libbinder",
        "libgui",
        "libui",
        "libutils",
    ],
}

運行結果

$ adb shell /data/server &
$ adb shell /data/client
data out is 0x12345678

描述

  1. 首先啓動server進程,用於創建BufferQueue、Producer和Consumer對象;
  2. 在client端通過ServiceManager獲取到Producer & Consumer的遠程代理;
  3. 通過Producer & Consumer的遠程代理,完成BufferQueue的一系列操作(操作內容同《最簡單的BufferQueue測試程序(一)》一樣)。

注意: Android規定,BufferQueue必須在Consumer進程中創建。因此該示例將consumerConnect()放在了server.cpp中。如果放在client.cpp中,在調用queueBuffer()時,程序會出現crash。

源碼下載

GitHub: mytest3

參考資料

Android BufferQueue自測試程序:BufferQueue_test.cpp: DISABLED_BufferQueueInAnotherProcess

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章