Android GraphicBuffer的dump保存成yuv文件
https://blog.csdn.net/liwenjie28/article/details/114830221
高通Android平台-应用空间操作framebuffer dump LCD总结
https://blog.csdn.net/eliot_shao/article/details/74926010
Android 图像显示系统 - 导出图层数据的方法介绍(dump GraphicBuffer raw data)
https://www.shuzhiduo.com/A/o75N78GedW/
高通平台dump graphics:
vendor.gralloc.disable_ubwc=1 ,ubwc禁掉
hlos_dev_la\lagvm\LINUX\android\frameworks\native\libs\renderengine\skia\SkiaGLRenderEngine.cpp
#include <cutils/properties.h>
#include <sys/stat.h>
status_t SkiaGLRenderEngine::drawLayers() {
char pro_value[256];
property_get(“debug.buffer.dump”,pro_value,0);
if(!strcmp(pro_value,“true”))
{
ALOGE(“dump_content_of_layers_to_file!”);
for (auto const layer : layers) {
if (layer->source.buffer.buffer != nullptr) {
sp gBuf = layer->source.buffer.buffer->getBuffer();
uint32_t height = gBuf->getHeight();
if (height < 1200) {
continue;
}
dump_content_of_layers_to_image(gBuf);
}
}
}
}
void SkiaGLRenderEngine::dump_content_of_layers_to_file(const sp& target)
{
ALOGE(“dump_content_of_layers_to_file begain”);
int result = -1;
void *addr = NULL;
static int DumpSurfaceCount = 0;
int32_t bufStride;
FILE * pfile = NULL;
char layername[100] ;
memset(layername,0,sizeof(layername));
uint32_t w, s, h, f;
w = target->getWidth();
h = target->getHeight();
s = target->getStride();
f = target->getPixelFormat();
android_dataspace d;
uint32_t buffer_size = 0;
d = HAL_DATASPACE_UNKNOWN;
buffer_size = s * h * bytesPerPixel(f);
bufStride = bytesPerPixel(f);
ALOGE("buffer_layer info w:%d h:%d s:%d f:%d d:%d size:%d", w, h, s, f, d, buffer_size);
if (DumpSurfaceCount > 120) {
DumpSurfaceCount = 0;
property_set("debug.buffer.dump", "false");
}
sprintf(layername,
"/data/local/tmp/buffer_layer_%d_frame_%d_%d_%d.yuv",
DumpSurfaceCount,
w,
h,
bufStride);
ALOGE("The dump file info : %s", layername);
DumpSurfaceCount ++;
pfile = fopen(layername,"w+");
if(pfile)
{
ALOGE("pfile dump file info : %p", pfile);
//获取FrameBufferSurface对应的ion地址
result = target->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &addr);
if(addr != NULL){
ALOGE("The addr : %p", addr);
int result = -1;
// system("mkdir /data/dump && chmod 777 /data/dump");
result = fwrite( (const void *)addr,
(size_t)( (buffer_size)),
1,
pfile);
if(result >0){
ALOGE("fwrite success!");
}else{
ALOGE("fwrite failed error %d", result);
}
}else{
ALOGE("lock buffer error!");
}
fclose(pfile);
target->unlock();
}
ALOGE("end The dump file info : %s", layername);
}
void SkiaGLRenderEngine::dump_content_of_layers_to_image(const sp& layerBuffer) {
if (layerBuffer.get() == nullptr) {
return;
}
static int sDumpCount = 0;
uint32_t width = layerBuffer->getWidth();
uint32_t height = layerBuffer->getHeight();
uint32_t stride = layerBuffer->getStride();
int32_t format = layerBuffer->getPixelFormat();
uint32_t buffer_size = stride * height * bytesPerPixel(format);
if (sDumpCount > 300) {
sDumpCount = 0;
property_set("debug.buffer.dump", "false");
}
char layerName[100] = {0};
sprintf(layerName, "/data/dump/gpu_layer_%u_frame_%u_%u_%u.jpg", sDumpCount++, width, height, buffer_size);
ALOGI("%s ,dumplayer buffer raw data to file :%s, format:%d,width %d,stride %d,", __FUNCTION__, layerName, format,width,stride);
int fd = -1;
fd = open(layerName, O_WRONLY | O_CREAT | O_TRUNC, 0664);
void* vaddr = nullptr;
status_t err = layerBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &vaddr);
if (fd != -1 && NO_ERROR == err && vaddr != nullptr) {
uint32_t c = 0x1;
write(fd, &width, 4);
write(fd, &height, 4);
write(fd, &format, 4);
write(fd, &c, 4);
size_t Bpp = bytesPerPixel(format);
for (size_t y=0 ; y<height ; y++) {
write(fd, vaddr, width*Bpp);
vaddr = (void *)((char *)vaddr + stride*Bpp);
}
close(fd);
}
}