概览

Android 中有多个窗口,每个窗口都是一个 Renderer,每个窗口渲染后把 buffer 传递给 Composer。由 Composer 来合成每个窗口的 buffer,最后发送给显示器显示。

Graphic data flow through Android

Graphic data flow through Android

Renderer 和 Composer 通过 BufferQueue 交互,它是一个生产者消费者模式。生产者和消费者之间传递的是 GraphicBuffer。

该文档会介绍 GraphicBuffer 的组成和跨进程传递的原理。

whiteboard_exported_image-15.png

GraphicBuffer Java

/**
 * Simple wrapper for the native GraphicBuffer class.
 * @hide
 */
public class GraphicBuffer implements Parcelable {
    ...
    private final int mWidth;
    private final int mHeight;
    private final int mFormat;
    private final int mUsage;
    // Note: do not rename, this field is used by native code
    private final long mNativeObject;

    // These two fields are only used by lock/unlockCanvas()
    private Canvas mCanvas;
    private int mSaveCount;
    ...
}

GraphicBuffer 实现了 Parcelable,所以它可以通过 binder 传递。它有 4 个成员描述 buffer 的属性:宽、高、像素格式 和 usage。

mNativeObject 指向的是 GraphicBufferWrapper,它包装了 GraphicBuffer native 指针。

class GraphicBufferWrapper {
public:
    explicit GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) {
        LOG_ALWAYS_FATAL_IF(buffer == nullptr, "creating a null GraphicBuffer");
    }
    const sp<GraphicBuffer>& get() const {
        return buffer;
    }
private:
    sp<GraphicBuffer> const buffer;
};

mCanvas 是在 lockCanvas() 创建的。

创建

/**
 * Creates new <code>GraphicBuffer</code> instance. This method will return null
 * if the buffer cannot be created.
 *
 * @param width The width in pixels of the buffer
 * @param height The height in pixels of the buffer
 * @param format The format of each pixel as specified in {@link PixelFormat}
 * @param usage Hint indicating how the buffer will be used
 *
 * @return A <code>GraphicBuffer</code> instance or null
 */
public static GraphicBuffer create(int width, int height, int format, int usage) {
    long nativeObject = nCreateGraphicBuffer(width, height, format, usage);
    if (nativeObject != 0) {
        return new GraphicBuffer(width, height, format, usage, nativeObject);
    }
    return null;
}

静态方法 GraphicBuffer.create() 中先调用 nCreateGraphicBuffer() 方法创建 GraphicBuffer native,然后创建一个 GraphicBuffer 对象返回。

static jlong android_graphics_GraphicBuffer_create(JNIEnv* env, jobject clazz,
        jint width, jint height, jint format, jint usage) {
    sp<GraphicBuffer> buffer = new GraphicBuffer(
            uint32_t(width), uint32_t(height), PixelFormat(format), uint32_t(usage),
            std::string("android_graphics_GraphicBuffer_create pid [") +
                    std::to_string(getpid()) +"]");

    status_t error = buffer->initCheck();
    if (error < 0) {
        ALOGW_IF(kDebugGraphicBuffer, "createGraphicBuffer() failed in GraphicBuffer.create()");
        return NULL;
    }

    GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(buffer);
    return reinterpret_cast<jlong>(wrapper);
}