GVKun编程网logo

Android 图像显示 -- setClientTarget的流程(android显示图片方式)

13

本文的目的是介绍Android图像显示--setClientTarget的流程的详细情况,特别关注android显示图片方式的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面

本文的目的是介绍Android 图像显示 -- setClientTarget的流程的详细情况,特别关注android显示图片方式的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解Android 图像显示 -- setClientTarget的流程的机会,同时也不会遗漏关于ajax 请求中 contentType 与 dataType 含义【data-id,target.dataset.id,var target = e.currentTarget;】、Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1、Android HttpClient GET或者POST请求基本使用方法、Android HttpClient的性能的知识。

本文目录一览:

Android 图像显示 -- setClientTarget的流程(android显示图片方式)

Android 图像显示 -- setClientTarget的流程(android显示图片方式)

 

SurfaceFlinger端的 setClientTarget的流程

 

11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#00 pc 00086f8f  /system/bin/surfaceflinger (android::Hwc2::impl::Composer::setClientTarget(unsigned long long, unsigned int, android::sp<android::GraphicBuffer> const&, int, android::hardware::graphics::common::V1_2::Dataspace, std::__1::vector<android::hardware::graphics::composer::V2_1::IComposerClient::Rect, std::__1::allocator<android::hardware::graphics::composer::V2_1::IComposerClient::Rect> > const&)+182)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#01 pc 00096791  /system/bin/surfaceflinger (android::impl::HWComposer::setClientTarget(android::HaldisplayId, unsigned int, android::sp<android::Fence> const&, android::sp<android::GraphicBuffer> const&, android::hardware::graphics::common::V1_2::Dataspace)+408)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#02 pc 0008e881  /system/bin/surfaceflinger (android::FramebufferSurface::advanceFrame()+332)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#03 pc 00122a55  /system/bin/surfaceflinger (android::compositionengine::impl::RenderSurface::queueBuffer(android::base::unique_fd_impl<android::base::DefaultCloser>)+436)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#04 pc 001069ed  /system/bin/surfaceflinger (android::compositionengine::impl::Output::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+168)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#05 pc 00100c89  /system/bin/surfaceflinger (android::compositionengine::impl::display::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+76)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#06 pc 001054ef  /system/bin/surfaceflinger (android::compositionengine::impl::Output::present(android::compositionengine::CompositionRefreshArgs const&)+114)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#07 pc 000ff727  /system/bin/surfaceflinger (android::compositionengine::impl::CompositionEngine::present(android::compositionengine::CompositionRefreshArgs&)+146)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#08 pc 000d600b  /system/bin/surfaceflinger (android::SurfaceFlinger::onMessageRefresh()+1530)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#09 pc 000d570d  /system/bin/surfaceflinger (android::SurfaceFlinger::onMessageInvalidate(long long, long long)+8784)
11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#10 pc 000b9907  /system/bin/surfaceflinger (android::impl::MessageQueue::Handler::handleMessage(android::Message const&)+94)
11-13 00:47:20.456   224   224 E HwcComposer: stackdump:#11 pc 00010179  /system/lib/libutils.so (android::Looper::pollInner(int)+288)
11-13 00:47:20.456   224   224 E HwcComposer: stackdump:#12 pc 0000ffff  /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+62)
11-13 00:47:20.456   224   224 E HwcComposer: stackdump:#13 pc 000b9dd1  /system/bin/surfaceflinger (android::impl::MessageQueue::waitMessage()+56)
11-13 00:47:20.456   224   224 E HwcComposer: stackdump:#14 pc 000cc50d  /system/bin/surfaceflinger (android::SurfaceFlinger::run()+6)
11-13 00:47:20.456   224   224 E HwcComposer: stackdump:#15 pc 000ff253  /system/bin/surfaceflinger (main+1182)
11-13 00:47:20.456   224   224 E HwcComposer: stackdump:#16 pc 0003253b  /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)
11-13 00:47:20.456   224   224 D HwcComposer: surfaceflinger dump data

 

 

HWC 端的 setClientTarget的流程

11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#00 pc 00013865  /vendor/lib/hw/hwcomposer.drm.so (android::DrmHwcTwo::Hwcdisplay::SetClientTarget(native_handle const*, int, int, hwc_region)+156)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#01 pc 000147c1  /vendor/lib/hw/hwcomposer.drm.so (int android::DrmHwcTwo::displayHook<HWC2::Error (android::DrmHwcTwo::Hwcdisplay::*)(native_handle const*, int, int, hwc_region), &(android::DrmHwcTwo::Hwcdisplay::SetClientTarget(native_handle const*, int, int, hwc_region)), native_handle const*, int, int, hwc_region>(hwc2_device*, unsigned long long, native_handle const*, int, int, hwc_region)+104)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#02 pc 0000774f  /vendor/bin/hw/android.hardware.graphics.composer@2.2-service.start (android::hardware::graphics::composer::V2_1::passthrough::detail::HwcHalImpl<android::hardware::graphics::composer::V2_2::hal::ComposerHal>::setClientTarget(unsigned long long, native_handle const*, int, int, std::__1::vector<hwc_rect, std::__1::allocator<hwc_rect> > const&)+40)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#03 pc 0000c5ad  /vendor/bin/hw/android.hardware.graphics.composer@2.2-service.start (android::hardware::graphics::composer::V2_1::hal::ComposerCommandEngine::executeSetClientTarget(unsigned short)+344)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#04 pc 0000b083  /vendor/bin/hw/android.hardware.graphics.composer@2.2-service.start (android::hardware::graphics::composer::V2_1::hal::ComposerCommandEngine::execute(unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, bool*, unsigned int*, android::hardware::hidl_vec<android::hardware::hidl_handle>*)+90)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#05 pc 0000a053  /vendor/bin/hw/android.hardware.graphics.composer@2.2-service.start (android::hardware::graphics::composer::V2_1::hal::detail::ComposerClientImpl<android::hardware::graphics::composer::V2_1::IComposerClient, android::hardware::graphics::composer::V2_1::hal::ComposerHal>::executeCommands(unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, std::__1::function<void (android::hardware::graphics::composer::V2_1::Error, bool, unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&)>)+82)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#06 pc 0001df97  /vendor/lib/android.hardware.graphics.composer@2.2.so (android::hardware::graphics::composer::V2_2::BnHwComposerClient::_hidl_executeCommands_2_2(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+294)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#07 pc 0001eaeb  /vendor/lib/android.hardware.graphics.composer@2.2.so (android::hardware::graphics::composer::V2_2::BnHwComposerClient::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+2414)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#08 pc 000546d9  /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+96)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#09 pc 000536a7  /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+974)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#10 pc 00053239  /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+56)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#11 pc 00006d75  /vendor/bin/hw/android.hardware.graphics.composer@2.2-service.start (main+216)
11-13 00:47:27.685   337   337 E hwc-drm-two: stackdump:#12 pc 0003253b  /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)

 

ajax 请求中 contentType 与 dataType 含义【data-id,target.dataset.id,var target = e.currentTarget;】

ajax 请求中 contentType 与 dataType 含义【data-id,target.dataset.id,var target = e.currentTarget;】

contentType: 告诉服务器,我要发什么类型的数据

dataType: ''json'',:我要接受什么类型的数据

 属性    data-id=“222”;

var target = e.currentTarget;

target.dataset.id 值为 222。

 

 1     $(''.category-wrap'').on(''click'', ''.row-product-category.now .delete'',
 2             function(e) {
 3                 var target = e.currentTarget;
 4                 $.confirm(''确定么?'', function() {
 5                     $.ajax({
 6                         url : deleteUrl,
 7                         type : ''POST'',
 8                         data : {
 9                             productCategoryId : target.dataset.id,
10                             shopId : ''''
11                         },
12                         dataType : ''json'',
13                         success : function(data) {
14                             if (data.success) {
15                                 $.toast(''删除成功!'');
16                                 getlist();
17                             } else {
18                                 $.toast(''删除失败!'');
19                             }
20                         }
21                     });
22                 });
23             });

 

 1 $.ajax({
 2             url : addUrl,
 3             type : ''POST'',
 4             data : JSON.stringify(productCategoryList),
 5             contentType : ''application/json'',
 6             success : function(data) {
 7                 if (data.success) {
 8                     $.toast("提交成功!");
 9                     getlist();
10                 } else {
11                     $.toast("提交失败!");
12                 }
13             }
14         });

Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1

Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1


必读:

Android 12(S) 图像显示系统 - 开篇


 

一、前言

SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时,会把待合成的图层Layers通过renderengine(SkiaglrenderEngine)绘制到一块GraphicBuffer中,然后把这块GraphicBuffer图形缓存通过调用setClientTarget传递给HWC模块,HWC进一步处理后把这个GraphicBuffer中的图像呈现到屏幕上。

本篇文章,我们先聚焦一点做介绍:用于存储GPU合成后的图形数据的GraphicBuffer是从哪里来的?下面的讲解会围绕这个问题展开。

 

二、从dumpsys SurfaceFlinger中的信息谈起

如果你查看过dumpsys SurfaceFlinger的信息,也许你注意过一些GraphicBufferAllocator/GraphicBufferMapper打印出的一些信息,这些信息记录了所有通过Gralloc模块allocate和import的图形缓存的信息。

如下是在我的平台下截取的dumpsys SurfaceFlinger部分信息:

GraphicBufferAllocator buffers:
    Handle |        Size |     W (Stride) x H | Layers |   Format |      Usage | Requestor
0xf3042b90 | 8100.00 KiB | 1920 (1920) x 1080 |      1 |        1 | 0x    1b00 | FramebufferSurface
0xf3042f30 | 8100.00 KiB | 1920 (1920) x 1080 |      1 |        1 | 0x    1b00 | FramebufferSurface
0xf3046020 | 8100.00 KiB | 1920 (1920) x 1080 |      1 |        1 | 0x    1b00 | FramebufferSurface
Total allocated by GraphicBufferAllocator (estimate): 24300.00 KB
Imported gralloc buffers:
+ name:FramebufferSurface, id:e100000000, size:8.3e+03KiB, w/h:780x438, usage: 0x40001b00, req fmt:5, fourcc/mod:875713089/576460752303423505, dataspace: 0x0, compressed: true
	planes: B/G/R/A:	 w/h:780x440, stride:1e00 bytes, size:818000
+ name:FramebufferSurface, id:e100000001, size:8.3e+03KiB, w/h:780x438, usage: 0x40001b00, req fmt:5, fourcc/mod:875713089/576460752303423505, dataspace: 0x0, compressed: true
	planes: B/G/R/A:	 w/h:780x440, stride:1e00 bytes, size:818000
+ name:FramebufferSurface, id:e100000002, size:8.3e+03KiB, w/h:780x438, usage: 0x40001b00, req fmt:5, fourcc/mod:875713089/576460752303423505, dataspace: 0x0, compressed: true
	planes: B/G/R/A:	 w/h:780x440, stride:1e00 bytes, size:818000
Total imported by gralloc: 5e+04KiB

上面的信息中可以看到一些儿冥冥之中貌似、似乎、好像很有意思的字眼:FramebufferSurface

作为Requestor的FramebufferSurface去请求分配了三块图形缓存,还规定了width、height、format、usage等信息。


 

如上你看到的这3块GraphicBuffer,就是用来存储cpu合成后的图形数据的。

 


 

三、创建与初始化FramebufferSurface的流程

FramebufferSurface的初始化逻辑需要从SurfaceFlinger的初始化谈起,在文章Android 12(S) 图像显示系统 - SurfaceFlinger的启动和消息队列处理机制(四)

中,曾分析过,SurfaceFlinger::init()中会去注册HWC的回调函数mCompositionEngine->getHwComposer().setCallback(this),当第一次注册callback时,onComposerHalHotplug()会立即在调用registerCallback()的线程中被调用,并跨进程回调到SurfaceFlinger::onComposerHalHotplug。然后一路飞奔:

SurfaceFlinger::processdisplayAdded这个方法中去创建了BufferQueue和FramebufferSurface,简单理解为连接上了显示屏幕(display),那就要给准备一个BufferQueue,以便GPU合成UI等图层时,可以向这个BufferQueue索要GraphicBuffer来存储合成后的图形数据,再呈现到屏幕上去(我的傻瓜式理解)

摘取关键代码如下:

[/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp]
void SurfaceFlinger::processdisplayAdded(const wp<IBinder>& displayToken,
                                         const displayDeviceState& state) {
    ......
    sp<compositionengine::displaySurface> displaySurface; 
    sp<IGraphicBufferProducer> producer;
    // 创建BufferQueue,获取到生产者和消费者,而且消费者不是SurfaceFlinger哦
    sp<IGraphicBufferProducer> bqProducer;
    sp<IGraphicBufferConsumer> bqConsumer;
    getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);

    if (state.isVirtual()) { // 虚拟屏幕,不管它
        const auto displayId = VirtualdisplayId::tryCast(compositiondisplay->getId());
        LOG_FATAL_IF(!displayId);
        auto surface = sp<VirtualdisplaySurface>::make(getHwComposer(), *displayId, state.surface,
                                                       bqProducer, bqConsumer, state.displayName);
        displaySurface = surface;
        producer = std::move(surface);
    } else { // 看这个case
        ALOGE_IF(state.surface != nullptr,
                 "adding a supported display, but rendering "
                 "surface is provided (%p), ignoring it",
                 state.surface.get());
        const auto displayId = PhysicaldisplayId::tryCast(compositiondisplay->getId());
        LOG_FATAL_IF(!displayId);
        // 创建了FramebufferSurface对象,FramebufferSurface继承自compositionengine::displaySurface
        // FramebufferSurface是作为消费者的角色工作的,消费SF GPU合成后的图形数据
        displaySurface =
                sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer,
                                             state.physical->activeMode->getSize(),
                                             ui::Size(maxGraphicsWidth, maxGraphicsHeight));
        producer = bqProducer;
    }

    LOG_FATAL_IF(!displaySurface);
    // 创建displayDevice,其又去创建RenderSurface,作为生产者角色工作,displaySurface就是FramebufferSurface对象
    const auto display = setupNewdisplayDeviceInternal(displayToken, std::move(compositiondisplay),
                                                       state, displaySurface, producer);
    mdisplays.emplace(displayToken, display);
    ......   
}

瞅一瞅 FramebufferSuraface的构造函数,没啥复杂的,就是一些设置,初始化一些成员

FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicaldisplayId displayId,
                                       const sp<IGraphicBufferConsumer>& consumer,
                                       const ui::Size& size, const ui::Size& maxSize)
      : ConsumerBase(consumer),
        mdisplayId(displayId),
        mMaxSize(maxSize),
        mCurrentBufferSlot(-1),
        mCurrentBuffer(),
        mCurrentFence(Fence::NO_FENCE),
        mHwc(hwc),
        mHasPendingrelease(false),
        mPrevIoUsBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
        mPrevIoUsBuffer() {
    ALOGV("Creating for display %s", to_string(displayId).c_str());

    mName = "FramebufferSurface";
    mConsumer->setConsumerName(mName); // 设置消费者的名字是 "FramebufferSurface"
    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |  // 设置usage
                                       GRALLOC_USAGE_HW_RENDER |
                                       GRALLOC_USAGE_HW_COMPOSER);
    const auto limitedSize = limitSize(size);
    mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height); // 设置buffer 大小
    mConsumer->setMaxAcquiredBufferCount( 
            SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
}

 

再进到SurfaceFlinger::setupNewdisplayDeviceInternal中看看相关的逻辑:

[/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp]
sp<displayDevice> SurfaceFlinger::setupNewdisplayDeviceInternal(
        const wp<IBinder>& displayToken,
        std::shared_ptr<compositionengine::display> compositiondisplay,
        const displayDeviceState& state,
        const sp<compositionengine::displaySurface>& displaySurface, 
        const sp<IGraphicBufferProducer>& producer) {
    ......
    creationArgs.displaySurface = displaySurface;  // displaySurface就是FramebufferSurface对象   
    
    // producer是前面processdisplayAdded中创建的
    auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
    auto nativeWindow = nativeWindowSurface->getNativeWindow();
    creationArgs.nativeWindow = nativeWindow;

    ....
    // 前面一大坨代码是在初始话creationArgs,这些参数用来创建displayDevice
    // creationArgs.nativeWindow会把前面创建的producer关联到了displayDevice
    sp<displayDevice> display = getFactory().createdisplayDevice(creationArgs);
    
    // 后面一大坨,对display进行了些设置
    if (!state.isVirtual()) {
        display->setActiveMode(state.physical->activeMode->getId());
        display->setDeviceProductInfo(state.physical->deviceProductInfo);
    }
    ....
}

 

接下来就是 displayDevice 的构造函数了,里面主要是创建了RenderSurface对象,然后对其进行初始化

[/frameworks/native/services/surfaceflinger/displayDevice.cpp]
displayDevice::displayDevice(displayDeviceCreationArgs& args)
      : mFlinger(args.flinger),
        mHwComposer(args.hwComposer),
        mdisplayToken(args.displayToken),
        mSequenceId(args.sequenceId),
        mConnectionType(args.connectionType),
        mCompositiondisplay{args.compositiondisplay},
        mPhysicalOrientation(args.physicalOrientation),
        mSupportedModes(std::move(args.supportedModes)),
        mIsPrimary(args.isPrimary) {
    mCompositiondisplay->editState().isSecure = args.isSecure;
    // 创建RenderSurface,args.nativeWindow 即为producer,指向生产者
    mCompositiondisplay->createRenderSurface(
            compositionengine::RenderSurfaceCreationArgsBuilder()
                    .setdisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get()))
                    .setdisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get()))
                    .setNativeWindow(std::move(args.nativeWindow))
                    .setdisplaySurface(std::move(args.displaySurface)) // displaySurface就是FramebufferSurface对象
                    .setMaxTextureCacheSize(
                            static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers))
                    .build());

    if (!mFlinger->mdisableClientCompositionCache &&
        SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
        mCompositiondisplay->createClientCompositionCache(
                static_cast<uint32_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers));
    }

    mCompositiondisplay->createdisplayColorProfile(
            compositionengine::displayColorProfileCreationArgs{args.hasWideColorGamut,
                                                               std::move(args.hdrCapabilities),
                                                               args.supportedPerFrameMetadata,
                                                               args.hwcColorModes});

    if (!mCompositiondisplay->isValid()) {
        ALOGE("Composition display did not validate!");
    }
    // 初始化RenderSurface
    mCompositiondisplay->getRenderSurface()->initialize();

    setPowerMode(args.initialPowerMode);

    // initialize the display orientation transform.
    setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
}

本文作者@二的次方  2022-05-10 发布于博客园

RenderSurface作为生产者的角色工作,构造函数如下,留意启成员displaySurface就是SurfaceFlinger中创建的FramebufferSurface对象

也就是 作为生产者的RenderSurface中持有 消费者的引用 displaySurface,可以呼叫FramebufferSurface的方法

[ /frameworks/native/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp]
RenderSurface::RenderSurface(const CompositionEngine& compositionEngine, display& display,
                             const RenderSurfaceCreationArgs& args)
      : mCompositionEngine(compositionEngine),
        mdisplay(display),
        mNativeWindow(args.nativeWindow),
        mdisplaySurface(args.displaySurface),  // displaySurface就是FramebufferSurface对象
        mSize(args.displayWidth, args.displayHeight),
        mMaxTextureCacheSize(args.maxTextureCacheSize) {
    LOG_ALWAYS_FATAL_IF(!mNativeWindow);
}

 

我们看看他的RenderSurface::initialize()方法

[/frameworks/native/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp]
void RenderSurface::initialize() {
    ANativeWindow* const window = mNativeWindow.get();

    int status = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
    ALOGE_IF(status != NO_ERROR, "Unable to connect BQ producer: %d", status);
    status = native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
    ALOGE_IF(status != NO_ERROR, "Unable to set BQ format to RGBA888: %d", status);
    status = native_window_set_usage(window, DEFAULT_USAGE);
    ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for GPU rendering: %d", status);
}

上述方法也很简单,就是作为producer去和BufferQueue建立connect,并设置format为RGBA_8888,设置usage为GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE

 


为了验证上述分析的流程是正确的,我在BufferQueueProducer::connect中加log来打印调用栈的信息,如下,是不是和分析的一样啊

11-13 00:52:58.497   227   227 D BufferQueueProducer: connect[1303] /vendor/bin/hw/android.hardware.graphics.composer@2.4-service start
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#00 pc 0005e77f  /system/lib/libgui.so (android::BufferQueueProducer::connect(android::sp<android::IProducerListener> const&, int, bool, android::IGraphicBufferProducer::QueueBufferOutput*)+1282)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#01 pc 000a276b  /system/lib/libgui.so (android::Surface::connect(int, android::sp<android::IProducerListener> const&, bool)+138)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#02 pc 0009de41  /system/lib/libgui.so (android::Surface::hook_perform(ANativeWindow*, int, ...)+128)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#03 pc 00121b1d  /system/bin/surfaceflinger (android::compositionengine::impl::RenderSurface::initialize()+12)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#04 pc 00083cc5  /system/bin/surfaceflinger (android::displayDevice::displayDevice(android::displayDeviceCreationArgs&)+1168)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#05 pc 000d8bed  /system/bin/surfaceflinger (android::SurfaceFlinger::processdisplayAdded(android::wp<android::IBinder> const&, android::displayDeviceState const&)+4440)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#06 pc 000d0db5  /system/bin/surfaceflinger (android::SurfaceFlinger::processdisplayChangesLocked()+2436)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#07 pc 000cef6b  /system/bin/surfaceflinger (android::SurfaceFlinger::processdisplayHotplugEventsLocked()+6422)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#08 pc 000d2c7f  /system/bin/surfaceflinger (android::SurfaceFlinger::onComposerHalHotplug(unsigned long long, android::hardware::graphics::composer::V2_1::IComposerCallback::Connection)+334)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#09 pc 0009afab  /system/bin/surfaceflinger (_ZN7android12_GLOBAL__N_122ComposerCallbackBridge9onHotplugEyNS_8hardware8graphics8composer4V2_117IComposerCallback10ConnectionE$d689f7ac1c60e4abeed02ca92a51bdcd+20)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#10 pc 0001bb97  /system/lib/android.hardware.graphics.composer@2.1.so (android::hardware::graphics::composer::V2_1::BnHwComposerCallback::_hidl_onHotplug(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+166)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#11 pc 000275e9  /system/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BnHwComposerCallback::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+228)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#12 pc 00054779  /system/lib/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+96)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#13 pc 0004fc67  /system/lib/libhidlbase.so (android::hardware::IPCThreadState::transact(int, unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int)+2174)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#14 pc 0004f2e5  /system/lib/libhidlbase.so (android::hardware::BpHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+36)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#15 pc 0002bdf1  /system/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BpHwComposerClient::_hidl_registerCallback_2_4(android::hardware::IInterface*, android::hardware::details::HidlInstrumentor*, android::sp<android::hardware::graphics::composer::V2_4::IComposerCallback> const&)+296)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#16 pc 0002ed8d  /system/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BpHwComposerClient::registerCallback_2_4(android::sp<android::hardware::graphics::composer::V2_4::IComposerCallback> const&)+34)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#17 pc 00085627  /system/bin/surfaceflinger (android::Hwc2::impl::Composer::registerCallback(android::sp<android::hardware::graphics::composer::V2_4::IComposerCallback> const&)+98)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#18 pc 00092d63  /system/bin/surfaceflinger (android::impl::HWComposer::setCallback(android::HWC2::ComposerCallback*)+2206)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#19 pc 000cd35b  /system/bin/surfaceflinger (android::SurfaceFlinger::init()+438)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#20 pc 000feb03  /system/bin/surfaceflinger (main+862)
11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#21 pc 0003253b  /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)
11-13 00:52:58.582   227   227 D BufferQueueProducer: connect[1307] /vendor/bin/hw/android.hardware.graphics.composer@2.4-service end

注意 本文作者@二的次方  2022-05-10 发布于博客园

注意 本文作者@二的次方  2022-05-10 发布于博客园

注意 本文作者@二的次方  2022-05-10 发布于博客园

这里有一个小细节要留意下,因为SurfaceFlinger::onComposerHalHotplug是HWC回调过来的,所以代码执行是在android.hardware.graphics.composer@2.4-service这个进程中的。

BufferQueueProducer::connect中记录的mConnectedPid就是composer service的PID

[ /frameworks/native/libs/gui/BufferQueueProducer.cpp]
mCore->mConnectedPid = BufferQueueThreadState::getCallingPid();

在dump BufferQueue的信息时,根据PID获取的 producer name 也就是 android.hardware.graphics.composer@2.4-service

[/frameworks/native/libs/gui/BufferQueueCore.cpp]
void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
    ...
    getProcessName(mConnectedPid, producerProcName);
    getProcessName(pid, consumerProcName);
    ....
}

如下是我的平台dumpsys SurfaceFlinger的信息打印出来的Composition RenderSurface State的信息,看看是不是和代码的设置都有对应起来:

Android HttpClient GET或者POST请求基本使用方法

Android HttpClient GET或者POST请求基本使用方法

在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务。你可以把HttpClient想象成一个浏览器,通过它的API我们可以很方便的发出GET,POST请求(它的功能远不止这些,这里只介绍如何使用HttpClient发起GET或者POST请求)


GET 方式


//先将参数放入List,再对参数进行URL编码
List params = new LinkedList();
params.add(new BasicNameValuePair("param1", "中国"));
params.add(new BasicNameValuePair("param2", "value2"));
//对参数编码
String param = URLEncodedUtils.format(params, "UTF-8");
//baseUrl
String baseUrl = "http://ubs.free4lab.com/php/method.php";
//将URL与参数拼接
HttpGet getMethod = new HttpGet(baseUrl + "?" + param);


HttpClient httpClient = new DefaultHttpClient();
try {
HttpResponse response = httpClient.execute(getMethod); //发起GET请求
Log.i(TAG, "resCode = " + response.getStatusLine().getStatusCode()); //获取响应码
Log.i(TAG, "result = " + EntityUtils.toString(response.getEntity(), "utf-8"));//获取服务器响应内容
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


POST方式

 


//和GET方式一样,先将参数放入List
params = new LinkedList();
params.add(new BasicNameValuePair("param1", "Post方法"));
params.add(new BasicNameValuePair("param2", "第二个参数"));


try {
HttpPost postMethod = new HttpPost(baseUrl);
postMethod.setEntity(new UrlEncodedFormEntity(params, "utf-8")); //将参数填入POST Entity中


HttpResponse response = httpClient.execute(postMethod); //执行POST方法
Log.i(TAG, "resCode = " + response.getStatusLine().getStatusCode()); //获取响应码
Log.i(TAG, "result = " + EntityUtils.toString(response.getEntity(), "utf-8")); //获取响应内容


} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Android HttpClient的性能

Android HttpClient的性能

我开发的 Android应用程序使用大量的http请求到Web服务.首先,我在每个请求之前创建一个新的HttpClient实例.
为了提高性能,我尝试在许多线程中执行请求.所以,我创建了一个HttpClient实例,由所有线程共享,使用ThreadSafeConnectionManager:
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http",PlainSocketFactory.getSocketFactory(),80));

BasicHttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(params,100);
HttpProtocolParams.setVersion(params,HttpVersion.HTTP_1_1);
HttpProtocolParams.setUseExpectContinue(params,true);

ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(params,registry);
HttpClient client = new DefaultHttpClient(connManager,params);

但表现却下降了,让我感到惊讶.我已经测量了时间,以这样的方式排出要求:

long startTime = System.currentTimeMillis();
HttpResponse response = client.execute(postRequest);
long reqTime = System.currentTimeMillis() - startTime;
Log.i("SyncTimer","Request time:" + reqTime);

这里是一个日志,我可以用简单的DefaultHttpClient来获取每个请求没有参数的新实例:

01-11 11:10:51.136: INFO/SyncTimer(18400): Request time:1076
01-11 11:10:54.686: INFO/SyncTimer(18400): Request time:1051
01-11 11:10:57.996: INFO/SyncTimer(18400): Request time:1054
01-11 11:10:59.166: INFO/SyncTimer(18400): Request time:1070
01-11 11:11:00.346: INFO/SyncTimer(18400): Request time:1172
01-11 11:11:02.656: INFO/SyncTimer(18400): Request time:1043

和ThreadSafeClientConnManager和单个HttpClient实例得到的结果:

01-11 11:06:06.926: INFO/SyncTimer(18267): Request time:7001
01-11 11:06:10.412: INFO/SyncTimer(18267): Request time:3385
01-11 11:06:20.222: INFO/SyncTimer(18267): Request time:9801
01-11 11:06:23.622: INFO/SyncTimer(18267): Request time:2058
01-11 11:06:29.906: INFO/SyncTimer(18267): Request time:6268
01-11 11:06:34.746: INFO/SyncTimer(18267): Request time:3525
01-11 11:06:50.302: INFO/SyncTimer(18267): Request time:15551

会发生什么,我该怎么办?

UPDATE

使用保持活力的优势 – 是我想要的.但是当我为每个请求连接创建新的HttpClient实例不能重复使用.尽管如此,这样的版本运行速度更快,但是对于我来说这是不清楚的.

解决方法

这一切都很简单.默认情况下,HttpClient只允许与HTTP规范要求的同一目标主机的两个并发连接.因此,您的工作线程有效地消耗大部分执行时间,等待这两个连接可用.

您应该增加“每条路线的最大连接数”限制,以减少/消除工作线程争用.

您可能还想查看Apache HttpComponents项目使用的基准测量HttpClient的性能.

http://wiki.apache.org/HttpComponents/HttpClient3vsHttpClient4vsHttpCore

关于Android 图像显示 -- setClientTarget的流程android显示图片方式的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于ajax 请求中 contentType 与 dataType 含义【data-id,target.dataset.id,var target = e.currentTarget;】、Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1、Android HttpClient GET或者POST请求基本使用方法、Android HttpClient的性能的相关信息,请在本站寻找。

本文标签: