【Android】从SurfaceFlinger中获取各layer图片(4)再回顾

从SurfaceFlinger中获取各layer图片的试验可以加深对GraphicBuffer和Layer的理解。

dumpsys SurfaceFlinger中打印的Slot信息中有GraphicBuffer的指针,可以帮助我们了解QueueBufferCore.

这个试验最初的出发点是根据图像的存储内存,再获取到这个数据,通过保存为图片的直观形式展现出来。

其实系统截图命令screencap也是类似的原理和实现(当然,我这里的保存图片就是从screencap里copy出来的方法)

frameworks/base/cmds/screencap/screencap.cpp

里面从surfaceflinger里面获取到了合成完成的GraphicBuffer,即屏幕截图画面

201    sp<GraphicBuffer> outBuffer;
202    status_t result = ScreenshotClient::capture(display, Rect(), 0 /* reqWidth */,
203            0 /* reqHeight */, INT32_MIN, INT32_MAX, /* all layers */ false, captureOrientation,
204            &outBuffer);
205    if (result != NO_ERROR) {
206        close(fd);
207        _exit(1);
208    }

再通过lock方法获取到存储地址base

  result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);

我们的试验中,显示出了GraphicBuffer的binder传送过程,

通过lockAsync方法获取到地址base

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

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

               

有了地址base,就可以使用screencap里面的方法来保存为图片了

217    w = outBuffer->getWidth();
218    h = outBuffer->getHeight();
219    s = outBuffer->getStride();
220    f = outBuffer->getPixelFormat();
221    d = HAL_DATASPACE_UNKNOWN;
222    size = s * h * bytesPerPixel(f);
223
224    if (png) {
225        const SkImageInfo info =
226            SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType, dataSpaceToColorSpace(d));
227        SkPixmap pixmap(info, base, s * bytesPerPixel(f));
228        struct FDWStream final : public SkWStream {
229          size_t fBytesWritten = 0;
230          int fFd;
231          FDWStream(int f) : fFd(f) {}
232          size_t bytesWritten() const override { return fBytesWritten; }
233          bool write(const void* buffer, size_t size) override {
234            fBytesWritten += size;
235            return size == 0 || ::write(fFd, buffer, size) > 0;
236          }
237        } fdStream(fd);
238        (void)SkEncodeImage(&fdStream, pixmap, SkEncodedImageFormat::kPNG, 100);
239        if (fn != NULL) {
240            notifyMediaScanner(fn);
241        }
242    } else {
243        uint32_t c = dataSpaceToInt(d);
244        write(fd, &w, 4);
245        write(fd, &h, 4);
246        write(fd, &f, 4);
247        write(fd, &c, 4);
248        size_t Bpp = bytesPerPixel(f);
249        for (size_t y=0 ; y<h ; y++) {
250            write(fd, base, w*Bpp);
251            base = (void *)((char *)base + s*Bpp);
252        }
253    }
254    close(fd);

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值