在Android surfaceflinger中访问层内容

在Android surfaceflinger中访问层内容,android,android-source,surfaceflinger,Android,Android Source,Surfaceflinger,我正在阅读层的内容,以检查其内容是否与应用程序在屏幕上呈现的内容相同。我正在阅读内容,然后由SurfaceFlinger合成。以下是HWComposer.cpp中HWCLayerVersion1的代码块::setAcquireFenceFd(),用于将图层内容/像素转储到原始文件 getLayer()->acquireFenceFd = fenceFd; private_handle_t *hnd = (private_handle_t*)getLayer()->ha

我正在阅读层的内容,以检查其内容是否与应用程序在屏幕上呈现的内容相同。我正在阅读内容,然后由SurfaceFlinger合成。以下是HWComposer.cppHWCLayerVersion1的代码块::setAcquireFenceFd(),用于将图层内容/像素转储到原始文件

    getLayer()->acquireFenceFd = fenceFd;
    private_handle_t *hnd = (private_handle_t*)getLayer()->handle; // the handle of the layer

    /*code for checking layer contents*/
    if(private_handle_t::validate(getLayer()->handle)==0){
             ALOGD("beta: we are gonna read a valid buffer-> %08x", intptr_t(getLayer()->handle));
             char filename[64];
             memset(filename, 0, 64);
             int name = clock();
             sprintf(filename, "/data/dump.%08x.raw", intptr_t(getLayer()->handle));                
             if(getLayer()->acquireFenceFd >= 0){
                  int ret = sync_wait(getLayer()->acquireFenceFd, -1);
                  if(ret < 0){
                        ALOGD("beta: sync_wait failed");
                  } else{
                      FILE *file = fopen(filename,"w+");
                      //ALOGD("beta: writing pixels");
                      fwrite((void*)hnd->base, hnd->size, 1, file);
                      close(getLayer()->acquireFenceFd);
                      //getLayer()->acquireFenceFd = -1;
                  } 
              } else {
                   ALOGD("beta: fencefd not valid");
              }
    }
getLayer()->acquireFenceFd=fenceFd;
private\u handle\u t*hnd=(private\u handle\u t*)getLayer()->handle;//层的句柄
/*用于检查图层内容的代码*/
if(private_handle_t::validate(getLayer()->handle)==0){
ALOGD(“beta:我们将读取一个有效的缓冲区->%08x”,intptr_t(getLayer()->handle));
字符文件名[64];
memset(文件名,0,64);
int name=clock();
sprintf(文件名“/data/dump.%08x.raw”,intptr_t(getLayer()->handle));
如果(getLayer()->acquireFenceFd>=0){
int ret=sync_wait(getLayer()->acquireFenceFd,-1);
如果(ret<0){
ALOGD(“beta:sync_wait failed”);
}否则{
FILE*FILE=fopen(文件名为“w+”);
//ALOGD(“beta:写入像素”);
写入((void*)hnd->base,hnd->size,1,文件);
关闭(getLayer()->acquireFenceFd);
//getLayer()->acquireFenceFd=-1;
} 
}否则{
ALOGD(“beta:fencefd无效”);
}
}
当我使用带有适当属性的IrfanView读取像素时,图像仅与实际内容略微相似,但颜色都被弄脏了。这背后的原因是什么?在我读取内容时是否呈现缓冲区?我是AOSP的新手,任何帮助都将不胜感激

如果您的主机(如果是模拟器)或设备支持图形加速,那么是的,您正在读取的缓冲区尚未完全呈现。
最新的Android版本支持同步机制,这意味着在渲染缓冲区(层)时,SurfaceFlinger可以获取缓冲区(层)。它们受到围栏机制的保护,确保不会显示未完全渲染的缓冲区

你说的“颜色都被弄脏了”是什么意思?你能发布好/坏的样本图片吗?(你可能需要在外部网站上这样做并发布一个链接——我想你需要更高的代表才能将它们内联)你在什么设备上进行测试?我非常抱歉发布这个问题。发布这篇文章几分钟后,我尝试了一个新的解决方案,一切正常!结果发现我在IrfanView中使用的分辨率不正确。无缘无故浪费了整整一天!但是有一个问题,我是否有必要等待acquireFenceFd,因为它似乎在没有它的情况下也能工作?但是sync_wait()应该等到缓冲区完全呈现,对吗?还是我遗漏了什么?如果你能帮忙,请你帮忙解决这个问题: