国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

android 13 systrace/perfetto視角分析SurfaceFlinger中截圖源碼分析

2023-10-06 12:28 作者:千里馬學框架  | 我要投稿

背景:

截圖是一種開發(fā)過程中經(jīng)常遇到的功能,但是這個功能底層是怎么實現(xiàn)的?今天就來給大家分享一下的,截圖的的實現(xiàn)原理。 截圖場景: 一般截圖都有以下幾個方式:

1、音量下鍵+power

2、systemui中下拉狀態(tài)欄,或者關(guān)機選著界面

3、adb shell命令行方式screencap命令方式

主要就是以上幾個,雖然場景不一樣,但是他們最后調(diào)用的截圖接口其實都是同一個,都是最后會調(diào)用到surfaceflinger中的截圖方法,下面就以adb shell命令行方式screencap案例分析,因為他的接口調(diào)用最為簡單,這次分析方式主要是使用perfetto的trace分析方式

screencap命令相關(guān)源碼及抓取perfetto操作

抓取perfetto方式:

1、輸入如下命令進行perfetto抓取

test@test:~$?aosp/external/perfetto/tools/record_android_trace?-o?$(date?+%Y%m%d_%H%M%S)_trace_file.perfetto-trace?-t?5s?-b?32mb?sched?freq?idle?am?wm?gfx?view?binder_driver?hal?dalvik?camera?input?res?memory?gfx?view?wm?am?ss?video?camera?hal?res?sync?idle?binder_driver?binder_lock?ss

2、另一個終端輸入如下命令進行截圖:

screencap -p /sdcard/1.png

代碼位置:

frameworks/base/cmds/screencap/screencap.cpp

int?main(int?argc,?char**?argv)
{
????std::optional<DisplayId>?displayId?=?SurfaceComposerClient::getInternalDisplayId();
???//省略部分
????ProcessState::self()->setThreadPoolMaxThreadCount(0);
????ProcessState::self()->startThreadPool();

????sp<SyncScreenCaptureListener>?captureListener?=?new?SyncScreenCaptureListener();
????//最為核心的方法ScreenshotClient::captureDisplay
????status_t?result?=?ScreenshotClient::captureDisplay(*displayId,?captureListener);
????if?(result?!=?NO_ERROR)?{
????????close(fd);
????????return?1;
????}

????ScreenCaptureResults?captureResults?=?captureListener->waitForResults();
????if?(captureResults.result?!=?NO_ERROR)?{
????????close(fd);
????????return?1;
????}
????ui::Dataspace?dataspace?=?captureResults.capturedDataspace;
????sp<GraphicBuffer>?buffer?=?captureResults.buffer;

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


????if?(png)?{
????????AndroidBitmapInfo?info;
????????info.format?=?flinger2bitmapFormat(buffer->getPixelFormat());
????????info.flags?=?ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
????????info.width?=?buffer->getWidth();
????????info.height?=?buffer->getHeight();
????????info.stride?=?buffer->getStride()?*?bytesPerPixel(buffer->getPixelFormat());

????????int?result?=?AndroidBitmap_compress(&info,?static_cast<int32_t>(dataspace),?base,
????????????????????????????????????????????ANDROID_BITMAP_COMPRESS_FORMAT_PNG,?100,?&fd,
????????????????????????????????????????????[](void*?fdPtr,?const?void*?data,?size_t?size)?->?bool?{
????????????????????????????????????????????????int?bytesWritten?=?write(*static_cast<int*>(fdPtr),
?????????????????????????????????????????????????????????????????????????data,?size);
????????????????????????????????????????????????return?bytesWritten?==?size;
????????????????????????????????????????????});
????
???//省略部分

????????if?(fn?!=?NULL)?{
????????????notifyMediaScanner(fn);
????????}
????}
?????
???//省略部分
????return?0;
}

其實整個screencap最為核心代碼就是只有一句: ScreenshotClient::captureDisplay 這個就是調(diào)用截圖相關(guān)的接口,該接口實現(xiàn)如下:

status_t?ScreenshotClient::captureDisplay(const?DisplayCaptureArgs&?captureArgs,
??????????????????????????????????????????const?sp<IScreenCaptureListener>&?captureListener)
?
{
????sp<gui::ISurfaceComposer>?s(ComposerServiceAIDL::getComposerService());
????if?(s?==?nullptr)?return?NO_INIT;

????binder::Status?status?=?s->captureDisplay(captureArgs,?captureListener);
????return?status.transactionError();
}

其實本質(zhì)是個跨進程調(diào)用,最后會調(diào)用到surfaceflinger的captureDisplay方法:

status_t?SurfaceFlinger::captureDisplay(DisplayId?displayId,
????????????????????????????????????????const?sp<IScreenCaptureListener>&?captureListener)
?
{
????ui::LayerStack?layerStack;
????wp<const?DisplayDevice>?displayWeak;
????ui::Size?size;
????ui::Dataspace?dataspace;
????{
????????Mutex::Autolock?lock(mStateLock);

????????const?auto?display?=?getDisplayDeviceLocked(displayId);
????????if?(!display)?{
????????????return?NAME_NOT_FOUND;
????????}

????????displayWeak?=?display;
????????layerStack?=?display->getLayerStack();
????????size?=?display->getLayerStackSpaceRect().getSize();

????????dataspace?=
????????????????pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
????}

????RenderAreaFuture?renderAreaFuture?=?ftl::defer([=]?{
????????return?DisplayRenderArea::create(displayWeak,?Rect(),?size,?dataspace,
?????????????????????????????????????????false?/*?useIdentityTransform?*/,
?????????????????????????????????????????false?/*?captureSecureLayers?*/);
????});

????auto?traverseLayers?=?[this,?layerStack](const?LayerVector::Visitor&?visitor)?{
????????traverseLayersInLayerStack(layerStack,?CaptureArgs::UNSET_UID,?visitor);
????};


????auto?future?=?captureScreenCommon(std::move(renderAreaFuture),?traverseLayers,?size,
??????????????????????????????????????ui::PixelFormat::RGBA_8888,?kAllowProtected,?kGrayscale,
??????????????????????????????????????captureListener);
????return?fenceStatus(future.get());
}

結(jié)合trace分析

具體上面的流程進行systrace、perfetto展示如下:

在這里插入圖片描述

這里顯示發(fā)起了一個跨進程調(diào)用,目標段是surfaceflinger進程

在這里插入圖片描述

trace的總結(jié)圖如下:

在這里插入圖片描述

surfaceflinger還有一個額外的回調(diào)客戶端操作:

在這里插入圖片描述

1、準備好buffer來繪制截圖

2、主導surfaceflinger需要相關(guān)的layer預處理

3、使用SkiaGl引擎進行進行相關(guān)的Layer繪制到新buffer

4、通知客戶端,回調(diào)listener


更多干貨內(nèi)容請關(guān)注,及私聊千里馬本人

android 13 systrace/perfetto視角分析SurfaceFlinger中截圖源碼分析的評論 (共 條)

分享到微博請遵守國家法律
东光县| 安多县| 嘉鱼县| 荣昌县| 中阳县| 沙湾县| 浪卡子县| 门头沟区| 徐水县| 大新县| 广州市| 宁乡县| 长宁县| 大足县| 珲春市| 陆川县| 仁布县| 凯里市| 思茅市| 甘谷县| 探索| 余姚市| 分宜县| 天津市| 临海市| 静乐县| 五大连池市| 永安市| 永济市| 泸州市| 仁布县| 武山县| 资溪县| 渭南市| 阿尔山市| 射洪县| 秦皇岛市| 吴川市| 汉阴县| 江城| 龙江县|