diff --git a/common/BufferMapper.cpp b/common/BufferMapper.cpp index 96e3eda..824b1c4 100644 --- a/common/BufferMapper.cpp +++ b/common/BufferMapper.cpp @@ -152,3 +152,42 @@ int BufferMapper::addCallback(gralloc_cb cb, void* ctx) { } return -1; } + +void BufferMapper::dump(buffer_handle_t b) { + ALOGD("Dump of buffer %p", b); + ALOGD("numFds=%d numInts=%d", b->numFds, b->numInts); + for (int i=0; i < 32; i++) { + ALOGD("data[%d] = %d", i, b->data[i]); + } +} + +bool BufferMapper::isGralloc1(buffer_handle_t b) { + return ((b->numFds + b->numInts) * sizeof(int) == + sizeof(cros_gralloc_handle) - sizeof(native_handle_t)); +} + +void BufferMapper::gralloc4ToGralloc1(buffer_handle_t in, struct cros_gralloc_handle* out) { + cros_gralloc4_handle_t g4h = (cros_gralloc4_handle_t)in; + + out->base.version = g4h->base.version; + out->base.numFds = g4h->num_planes; + out->base.numInts = (sizeof(cros_gralloc_handle) - sizeof(native_handle_t)) / sizeof(int) - out->base.numFds; + +#define COPY_ELEMENT(e) out->e = g4h->e + for (int i = 0; i < g4h->num_planes; i++) { + COPY_ELEMENT(fds[i]); + COPY_ELEMENT(strides[i]); + COPY_ELEMENT(offsets[i]); + COPY_ELEMENT(sizes[i]); + COPY_ELEMENT(sizes[i]); + COPY_ELEMENT(format_modifiers[2 * i]); + COPY_ELEMENT(format_modifiers[2 * i + 1]); + } + COPY_ELEMENT(width); + COPY_ELEMENT(height); + COPY_ELEMENT(format); + COPY_ELEMENT(tiling_mode); + COPY_ELEMENT(pixel_stride); + COPY_ELEMENT(droid_format); + COPY_ELEMENT(usage); +} diff --git a/common/BufferMapper.h b/common/BufferMapper.h index d688efa..b523c9a 100644 --- a/common/BufferMapper.h +++ b/common/BufferMapper.h @@ -5,6 +5,8 @@ #include #include +#include "gralloc_handle.h" + const int32_t GRALLOC1_FUNCTION_ADD_CALLBACK = 108; enum { GRALLOC_EVENT_ALLOCATE = 0, @@ -32,6 +34,10 @@ class BufferMapper { int unlockBuffer(buffer_handle_t b); int addCallback(gralloc_cb cb, void* ctx); + void dump(buffer_handle_t b); + bool isGralloc1(buffer_handle_t b); + void gralloc4ToGralloc1(buffer_handle_t in, struct cros_gralloc_handle* out); + private: BufferMapper(); int getGrallocDevice(); diff --git a/common/RemoteDisplay.cpp b/common/RemoteDisplay.cpp index f958efe..0912d74 100644 --- a/common/RemoteDisplay.cpp +++ b/common/RemoteDisplay.cpp @@ -11,6 +11,8 @@ #include "RemoteDisplay.h" +#include "BufferMapper.h" + //#define DEBUG_LAYER #ifdef DEBUG_LAYER #define LAYER_TRACE(...) ALOGD(__VA_ARGS__) @@ -154,17 +156,34 @@ int RemoteDisplay::sendDisplayPortReq() { return 0; } -int RemoteDisplay::createBuffer(buffer_handle_t buffer) { +int RemoteDisplay::createBuffer(buffer_handle_t b) { ALOGV("RemoteDisplay(%d)::%s", mSocketFd, __func__); + BufferMapper& mapper = BufferMapper::getMapper(); + buffer_info_event_t ev; + int64_t bufferId = (int64_t)b; + buffer_handle_t buffer = b; + bool isGralloc1Buffer = mapper.isGralloc1(b); + cros_gralloc_handle* gh = nullptr; + + if (isGralloc1Buffer) { + buffer = b; + } else { + gh = (cros_gralloc_handle*)malloc(sizeof(cros_gralloc_handle)); + mapper.gralloc4ToGralloc1(b, gh); + buffer = (buffer_handle_t)gh; + } memset(&ev, 0, sizeof(ev)); ev.event.type = DD_EVENT_CREATE_BUFFER; - ev.info.bufferId = (int64_t)buffer; + ev.info.bufferId = (int64_t)bufferId; ev.event.size = sizeof(ev) + sizeof(native_handle_t) + (buffer->numFds + buffer->numInts) * 4; + ALOGI("createBuffer size=%d, sizeof(cros_gralloc_handle)=%zd, numFd=%d numInts=%d native_handle=%zd size(ev)=%zd", + ev.event.size, sizeof(cros_gralloc_handle), buffer->numFds, buffer->numInts, sizeof(native_handle_t), sizeof(ev)); + if (_send(&(ev.event), sizeof(ev.event)) < 0) { ALOGE("RemoteDisplay(%d) failed to send create buffer event", mSocketFd); return -1; @@ -185,6 +204,8 @@ int RemoteDisplay::createBuffer(buffer_handle_t buffer) { return -1; } } + if (gh) + free(gh); return 0; } diff --git a/common/gralloc_handle.h b/common/gralloc_handle.h new file mode 100644 index 0000000..4797bb7 --- /dev/null +++ b/common/gralloc_handle.h @@ -0,0 +1,99 @@ +#ifndef _GRALLOC_HANDLE_H_ +#define _GRALLOC_HANDLE_H_ + +#include +#include + +#define DRV_MAX_PLANES 4 +#define DRV_MAX_FDS (DRV_MAX_PLANES + 1) + +struct cros_gralloc4_handle { + native_handle_t base; + /* + * File descriptors must immediately follow the native_handle_t base and used file + * descriptors must be packed at the beginning of this array to work with + * native_handle_clone(). + * + * This field contains 'num_planes' plane file descriptors followed by an optional metadata + * reserved region file descriptor if 'reserved_region_size' is greater than zero. + */ + int32_t fds[DRV_MAX_FDS]; + uint32_t strides[DRV_MAX_PLANES]; + uint32_t offsets[DRV_MAX_PLANES]; + uint32_t sizes[DRV_MAX_PLANES]; + bool from_kms; + uint32_t id; + uint32_t width; + uint32_t height; + uint32_t format; /* DRM format */ + uint64_t format_modifier; + uint64_t use_flags; /* Buffer creation flags */ + uint32_t magic; + uint32_t pixel_stride; + int32_t droid_format; + int32_t usage; /* Android usage. */ + uint32_t num_planes; + uint64_t reserved_region_size; + uint64_t total_size; /* Total allocation size */ + /* + * Name is a null terminated char array located at handle->base.data[handle->name_offset]. + */ + uint32_t name_offset; + uint32_t consumer_usage; + uint32_t producer_usage; + uint32_t yuv_color_range; // YUV Color range. + uint32_t is_updated; // frame updated flag + uint32_t is_encoded; // frame encoded flag + uint32_t is_encrypted; + uint32_t is_key_frame; + uint32_t is_interlaced; + uint32_t is_mmc_capable; + uint32_t compression_mode; + uint32_t compression_hint; + uint32_t codec; + uint32_t tiling_mode; + uint32_t format_modifiers[2 * DRV_MAX_PLANES]; +} __attribute__((packed)); + +typedef const struct cros_gralloc4_handle *cros_gralloc4_handle_t; + +/* + * Only use 32-bit integers in the handle. This guarantees that the handle is + * densely packed (i.e, the compiler does not insert any padding). + */ + +struct cros_gralloc_handle { + native_handle_t base; + int32_t fds[DRV_MAX_PLANES]; + uint32_t strides[DRV_MAX_PLANES]; + uint32_t offsets[DRV_MAX_PLANES]; + uint32_t sizes[DRV_MAX_PLANES]; + uint32_t format_modifiers[2 * DRV_MAX_PLANES]; + uint32_t width; + uint32_t height; + uint32_t format; /* DRM format */ + uint32_t tiling_mode; + uint32_t use_flags[2]; /* Buffer creation flags */ + uint32_t magic; + uint32_t pixel_stride; + int32_t droid_format; + int32_t usage; /* Android usage. */ + uint32_t consumer_usage; + uint32_t producer_usage; + uint32_t yuv_color_range; // YUV Color range. + uint32_t is_updated; // frame updated flag + uint32_t is_encoded; // frame encoded flag + uint32_t is_encrypted; + uint32_t is_key_frame; + uint32_t is_interlaced; + uint32_t is_mmc_capable; + uint32_t compression_mode; + uint32_t compression_hint; + uint32_t codec; + uint32_t aligned_width; + uint32_t aligned_height; +} __attribute__((packed)); + +typedef const struct cros_gralloc_handle *cros_gralloc_handle_t; + +#endif diff --git a/renderer/FastBufferDump.cpp b/renderer/FastBufferDump.cpp index 07f3065..ff453cb 100644 --- a/renderer/FastBufferDump.cpp +++ b/renderer/FastBufferDump.cpp @@ -3,6 +3,7 @@ #include #include "FastBufferDump.h" +#include "BufferMapper.h" //#define DEBUG_GL @@ -153,7 +154,6 @@ int FastBufferDump::dumpToPng(const char* path, const ImageData* image) { int FastBufferDump::run() { if (!mEnableDump) return -1; - BufferTexture bufTex(mHandle, true); uint32_t w = bufTex.getWidth(); uint32_t h = bufTex.getHeight();