[Android] SurfaceFlinger(4)から各レイヤーの画像を取得してレビューします

SurfaceFlingerから各レイヤーの画像を取得する実験により、GraphicBufferとLayerの理解を深めることができます。

dumpsys SurfaceFlingerに出力されるスロット情報にGraphicBufferポインターがあり、これはQueueBufferCoreを理解するのに役立ちます。

この実験の最初の出発点は、画像のストレージメモリに基づいてこのデータを取得し、画像として保存された直感的な形式で表示することです。

実際、システムのスクリーンショットコマンドscreencapも原理と実装が似ています(もちろん、ここで写真を保存する方法はscreencapからコピーすることです)

フレームワーク/ベース/ CMDS / SCREENCAP / screencap.cpp

内部では、合成されたGraphicBufferは、スクリーンショット画面であるsurfaceflingerから取得されます。

201     sp < GraphicBuffer >outBuffer ;
202     status_t 結果= ScreenshotClient :: CapturedisplayRect()、0 / * reqWidth * /、
 203             0 / * reqHeight * /、INT32_MININT32_MAX、/ *すべてのレイヤー* / falsecaptureOrientation204outBuffer);
205     ifresult!= NO_ERROR){
 206         closefd);
207         _exit(1);
208     }

次に、ロック方式でストレージアドレスベースを取得します

  結果= outBuffer- >ロックGraphicBuffer :: USAGE_SW_READ_OFTEN、&base);

私たちの実験では、GraphicBufferのバインダー転送プロセスが示されています。

lockAsyncメソッドを介してアドレスベースを取得します

        status_t res = buf-> lockAsync(0x00000003U | 0x00000030U、

                newDirtyRegion.bounds()、&vaddr、fenceFd);

               

アドレスベースを使用すると、screencapのメソッドを使用して画像として保存できます

217     w = outBuffer- > getWidth();
218     h = outBuffer- > getHeight();
219     s = outBuffer- > getStride();
220     f = outBuffer- > getPixelFormat();
221     d = HAL_DATASPACE_UNKNOWN ;
222    サイズ= s * h * bytesPerPixel(f);
223 
224     ifpng){
 225         const  SkImageInfo info =
 226             SkImageInfo :: Make(w、h、flinger2skia(f)、kPremul_SkAlphaTypedataSpaceToColorSpace(d));
227         SkPixmap  pixmapinfobase、s * bytesPerPixel(f));
228         struct  FDWStream 最終public  SkWStream {
 229           size_t fBytesWritten = 0;
230           int fFd ;
231          FDWStreamint f):fFd(f){}
 232           size_t  bytesWritten()const  override { return  fBytesWritten ; }
 233           bool  writeconst  void * buffersize_t  sizeoverride {
 234             fBytesWritten + = size ;
235            リターン サイズ== 0 || ::書き込みfFdバッファサイズ)> 0;
236          }
 237         } fdStreamfd);
238voidSkEncodeImage(&fdStreampixmapSkEncodedImageFormat :: kPNG、100);
239         iffn!= NULL){
 240             notifyMediaScannerfn);
241         }
 242     } else {
 243         uint32_t c = dataSpaceToInt(d);
244        書き込みfd、&​​w、4);
245        書き込みfd、&​​h、4);
246        書き込みfd、&​​f、4);
247        書き込みfd、&​​c、4);
248         size_t Bpp = bytesPerPixel(f);
249         forsize_t y = 0; y <h; y ++){
 250             writefdbase、w * Bpp);
251             base =(void *)((char *)base + s * Bpp);
252         }
 253     }
 254     closefd);

 

 

おすすめ

転載: blog.csdn.net/aaajj/article/details/105474888