//#include <iostream>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <iostream>
#include <array>
#include <limits>
#include <set>
#include <unordered_map>
#include <functional>
#include <memory>
#include <ostream>
#include <string>
#include <vector>
#include <map>
#include <optional>
#include <optional>
#include <chrono>
#include <mutex>
#include <thread>
#include <android/gui/IDisplayEventConnection.h>
#include <android/gui/ISurfaceComposer.h>
#include <binder/ProcessState.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
#include <inttypes.h>
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <sys/types.h>
#include <ui/BufferQueueDefs.h>
#include <ui/DisplayMode.h>
#include <ui/Rect.h>
#include <utils/Errors.h>
#include <utils/String8.h>
#include <limits>
#include <thread>
#include "ColorUtils.h"
#include "MockConsumer.h"
#include <utils/Log.h>
//
typedef uint8_t u8;
typedef int32_t u32;
#include <iostream>
#include <chrono>
#include <thread>
#include <android/gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceControl.h>
#include <gui/Surface.h>
#include <ui/Rect.h>
#include <gui/IConsumerListener.h>
using namespace android;
static const uint32_t TEST_DATA = 123456;
const uint32_t DEFAULT_WIDTH = 1;
const uint32_t DEFAULT_HEIGHT = 1;
// Default format before setDefaultBufferFormat is called
const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;
// Default transform hint before setTransformHint is called
//const uint32_t DEFAULT_TRANSFORM_HINT = 0;
// TODO: Make these constants in header
//const int DEFAULT_CONSUMER_USAGE_BITS = 0;
#define TEST_PRODUCER_USAGE_BITS (0)
// Parameters for a generic "valid" input for queueBuffer.
const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
const uint32_t QUEUE_BUFFER_INPUT_STICKY_TRANSFORM = 0;
const bool QUEUE_BUFFER_INPUT_GET_TIMESTAMPS = 0;
const int QUEUE_BUFFER_INPUT_SLOT = -1;
// Builder pattern to slightly vary *almost* correct input
// -- avoids copying and pasting
struct QueueBufferInputBuilder {
QueueBufferInputBuilder() {
timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
crop = QUEUE_BUFFER_INPUT_RECT;
scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
transform = QUEUE_BUFFER_INPUT_TRANSFORM;
fence = QUEUE_BUFFER_INPUT_FENCE;
stickyTransform = QUEUE_BUFFER_INPUT_STICKY_TRANSFORM;
getTimestamps = QUEUE_BUFFER_INPUT_GET_TIMESTAMPS;
slot = QUEUE_BUFFER_INPUT_SLOT;
}
IGraphicBufferProducer::QueueBufferInput build() {
return IGraphicBufferProducer::QueueBufferInput(
timestamp,
isAutoTimestamp,
dataSpace,
crop,
scalingMode,
transform,
fence,
stickyTransform,
getTimestamps,
slot);
}
private:
int64_t timestamp;
bool isAutoTimestamp;
android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
sp<Fence> fence;
uint32_t stickyTransform;
bool getTimestamps;
int slot;
};
// Create a generic "valid" input for queueBuffer
// -- uses the default buffer format, width, etc.
static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
return QueueBufferInputBuilder().build();
}
int main() {
sp<IGraphicBufferProducer> mProducer;
sp<IGraphicBufferConsumer> mConsumer;
const String16 PRODUCER_NAME = String16("BQTestProducer1");
const String16 CONSUMER_NAME = String16("BQTestConsumer1");
// pid_t forkPid = fork();
// if (forkPid == -1) {
// std::cout << "fork error" << std::endl;
// return -1;
// }
// if (forkPid == 0) {
// Child process
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
sp<IServiceManager> serviceManager = defaultServiceManager();
serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
ProcessState::self()->startThreadPool();
// IPCThreadState::self()->joinThreadPool();
// LOG_ALWAYS_FATAL("Shouldn't be here");
// }
// sp<IServiceManager> serviceManager = defaultServiceManager();
sp<IBinder> binderProducer =
serviceManager->getService(PRODUCER_NAME);
mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
sp<IBinder> binderConsumer =
serviceManager->getService(CONSUMER_NAME);
mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
sp<MockConsumer> mc(new MockConsumer);
//
mConsumer->consumerConnect(mc, false);
//
IGraphicBufferProducer::QueueBufferOutput output;
// ASSERT_EQ(OK,
auto ret = mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output);
if (ret != NO_ERROR) {
std::cout << "mProducer->connect fails:" << statusToString(ret) << std::endl;
return ret;
}
int slot = -1;
sp<Fence> fence;
sp<GraphicBuffer> buffer;
ret = mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
nullptr, nullptr);
if (ret < 0) {
std::cout << "mProducer->dequeueBuffer fails: " << ret << std::endl;
return ret;
}
if (slot == -1) {
std::cout << "slot is -1" << ret << std::endl;
return -1;
}
ret = mProducer->requestBuffer(slot, &buffer);
if (buffer == nullptr) {
std::cout << "mProducer->requestBuffer fails " << ret << std::endl;
return -1;
}
uint32_t *dataIn;
ret = buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void **>(&dataIn));
if (ret != OK) {
std::cout << "buffer->lock fails" << std::endl;
return ret;
}
*dataIn = TEST_DATA;
ret = buffer->unlock();
if (ret != OK) {
std::cout << "unlock fails" << std::endl;
return ret;
}
std::cout << "slot is:" << slot << std::endl;
IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
IGraphicBufferProducer::QueueBufferOutput output2;
ret = mProducer->queueBuffer(slot, input, &output2);
if (ret != NO_ERROR) {
std::cout << "queueBuffer fails: " << statusToString(ret) << std::endl;
return ret;
}
BufferItem item;
ret = mConsumer->acquireBuffer(&item, 0);
//
if (ret != OK) {
std::cout << "acquireBuffer fails:" << statusToString(ret) << std::endl;
return ret;
}
uint32_t *dataOut;
ret = item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void **>(&dataOut));
if (ret != OK) {
std::cout << "item.mGraphicBuffer->lock fails" << std::endl;
return ret;
}
if (*dataOut != TEST_DATA) {
std::cout << "dataOut!=TEST_DATA" << std::endl;
return -1;
} else {
std::cout << *dataOut << std::endl;
}
ret = item.mGraphicBuffer->unlock();
if (ret != OK) {
std::cout << "unlock fails" << std::endl;
return ret;
}
std::cout << "OK" << std::endl;
IPCThreadState::self()->joinThreadPool();
return 0;
}
The Usage of BufferQueue in one process
于 2024-06-23 11:37:57 首次发布