基于API 23
前篇:Android系統(tǒng)_Surface創(chuàng)建流程分析
申請(qǐng)Buffer
ViewRootImpl.draw
執(zhí)行遍歷 > 執(zhí)行Draw > draw方法 > 軟件繪制流程
private void performTraversals() {
...
relayoutWindow(params, viewVisibility, insetsPending);
...
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
performLayout(lp, mWidth, mHeight);
...
performDraw();
...
}
private void performDraw() {
draw(fullRedrawNeeded);
}
private void draw(boolean fullRedrawNeeded) {
if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
// 硬件加速 寥粹,繪制繪制流程
if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
...
mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
} else {
...
// 軟件繪制 流程
if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)) {
return;
}
}
}
ViewRootImpl.drawSoftware
主要三個(gè)步驟 申請(qǐng)Buffer集峦、繪制衰伯、繪制完成
private boolean drawSoftware(Surface surface, AttachInfo attachInfo,...) {
// Draw with software renderer.
final Canvas canvas;
...
canvas = mSurface.lockCanvas(dirty); //申請(qǐng)Buffer
...
mView.draw(canvas); //繪制
...
mSurface.unlockCanvasAndPost(canvas); //繪制完成
}
Surface.lockCanvas
執(zhí)行JNI層的nativeLockCanvas平夜,mNativeObject就是native層Surface指針
public Canvas lockCanvas(Rect inOutDirty)
throws Surface.OutOfResourcesException, IllegalArgumentException {
synchronized (mLock) {
checkNotReleasedLocked();
mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
}
}
android_view_Surface.cpp
創(chuàng)建一個(gè)Rect對(duì)象塘秦,確定要重繪制的區(qū)域昌妹,執(zhí)行Surface的lock方法來(lái)申請(qǐng)bugger橘忱,然后新建了一個(gè)SKBitmap紫岩,設(shè)置了內(nèi)存地址,并把這個(gè)bitmap放入了Canvas中
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); //轉(zhuǎn)換指針
...
Rect dirtyRect;
Rect* dirtyRectPtr = NULL;
if (dirtyRectObj) {
dirtyRect.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
dirtyRect.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
dirtyRect.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
dirtyRectPtr = &dirtyRect;
}
// 申請(qǐng)內(nèi)存Buffer
ANativeWindow_Buffer outBuffer;
status_t err = surface->lock(&outBuffer, dirtyRectPtr);
...
SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
convertPixelFormat(outBuffer.format),
kPremul_SkAlphaType);
// 新建一個(gè)SkBitmap 并進(jìn)行一系列設(shè)置
SkBitmap bitmap;
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
bitmap.setInfo(info, bpr);
if (outBuffer.width > 0 && outBuffer.height > 0) {
bitmap.setPixels(outBuffer.bits);
} else {
// be safe with an empty bitmap.
bitmap.setPixels(NULL);
}
// 把創(chuàng)建的bitmap 設(shè)置到Canvas中
Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
nativeCanvas->setBitmap(bitma
if (dirtyRectPtr) {
nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
dirtyRect.right, dirtyRect.bottom);
if (dirtyRectObj) {
env->SetIntField(dirtyRectObj, gRectClassInfo.left, dirtyRect.left);
env->SetIntField(dirtyRectObj, gRectClassInfo.top, dirtyRect.top);
env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right);
env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
// Create another reference to the surface and return it. This reference
// should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
// because the latter could be replaced while the surface is locked.
sp<Surface> lockedSurface(surface);
lockedSurface->incStrong(&sRefBaseOwner);
return (jlong) lockedSurface.get();
}
Surface.cpp
通過(guò)dequeueBuffer獲取一個(gè)ANativeWindowBuffer吝镣,之后構(gòu)造一個(gè)GraphicBuffer堤器,這個(gè)bugger用來(lái)傳遞繪制的元數(shù)據(jù)
BufferQueueProducer中dequeueBuffer,將分配的內(nèi)存放到mSlots中末贾,outSlot就是給應(yīng)用進(jìn)程mSlots的序號(hào)
BufferQueueProducer中requestBuffer闸溃,根據(jù)序號(hào),從mSlots拿到buffer
status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds){
ANativeWindowBuffer* out; int fenceFd = -1;
status_t err = dequeueBuffer(&out, &fenceFd); //從 GraphicBufferProduce 中 拿出來(lái)一個(gè) buffer
if (err == NO_ERROR) {
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));//放到backBuffer中
const Rect bounds(backBuffer->width, backBuffer->height);
.......
void* vaddr;
status_t res = backBuffer->lockAsync(//把buffer的handle中的地址傳到vaddr中
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
newDirtyRegion.bounds(), &vaddr, fenceFd);
if (res != 0) {
err = INVALID_OPERATION;
} else {
mLockedBuffer = backBuffer;
outBuffer->width = backBuffer->width;
outBuffer->height = backBuffer->height;
outBuffer->stride = backBuffer->stride;
outBuffer->format = backBuffer->format;
outBuffer->bits = vaddr;//buffer地址
}
return err // 返回GraphicBuffer
}
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
...
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
reqFormat, reqUsage, &mBufferAge,
enableFrameTimestamps ? &frameTimestamps
: nullptr);
if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);//根據(jù)需要拿到buffer
}
sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
*buffer = gbuf.get();
return OK;
}
View繪制
View.draw
執(zhí)行View的繪制流程
下面看常見(jiàn)的 canvas.drawRect
public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {
native_drawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
}
android_graphics_Canvas.cpp
static void drawRect(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
jfloat right, jfloat bottom, jlong paintHandle) {
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
}
SkiaCanvas.drawRect
執(zhí)行Skia庫(kù)的繪制方法
void SkiaCanvas::drawRect(float left, float top, float right, float bottom,
const SkPaint& paint) {
mCanvas->drawRectCoords(left, top, right, bottom, paint);
}
SkCanvas.drawRectCoords
執(zhí)行 到SkBitmap寫(xiě)入Buffer數(shù)據(jù)
void SkCanvas::drawRectCoords(SkScalar left, SkScalar top,
SkScalar right, SkScalar bottom,
const SkPaint& paint) {
TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()");
SkRect r;
r.set(left, top, right, bottom);
this->drawRect(r, paint);
}
void SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint,
const SkRect& r, SkScalar textSize) {
if (paint.getStyle() == SkPaint::kFill_Style) {
// fDevice 即SKBitmap 拱撵,從而實(shí)現(xiàn)將數(shù)據(jù)寫(xiě)入buffer
draw.fDevice->drawRect(draw, r, paint);
} else {
SkPaint p(paint);
p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth()));
draw.fDevice->drawRect(draw, r, p);
}
}
View繪制完成后通知刷新
Surface.unlockCanvasAndPost(canvas)
public void unlockCanvasAndPost(Canvas canvas) {
synchronized (mLock) {
checkNotReleasedLocked();
if (mHwuiContext != null) {
mHwuiContext.unlockAndPost(canvas);
} else {
// 走軟件繪制流程
unlockSwCanvasAndPost(canvas);
}
}
}
android_view.Surface.nativeUnlockCanvasAndPost
設(shè)置一個(gè)空的SkBitmap
然后執(zhí)行Surface的unlockANdPost函數(shù)
private void unlockSwCanvasAndPost(Canvas canvas) {
if (canvas != mCanvas) {
throw new IllegalArgumentException("canvas object must be the same instance that "
+ "was previously returned by lockCanvas");
}
if (mNativeObject != mLockedObject) {
Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
Long.toHexString(mLockedObject) +")");
}
if (mLockedObject == 0) {
throw new IllegalStateException("Surface was not locked");
}
try {
nativeUnlockCanvasAndPost(mLockedObject, canvas);
} finally {
nativeRelease(mLockedObject);
mLockedObject = 0;
}
}
Surface.cpp.unlockAndPost
解除buffer鎖定辉川,執(zhí)行queueBuffer最后執(zhí)行到GraphicBufferProducer的queueBuffer函數(shù),將buffer清除
status_t Surface::unlockAndPost()
{
int fd = -1;
status_t err = mLockedBuffer->unlockAsync(&fd);//通過(guò)Gralloc模塊拴测,最后是操作的ioctl
err = queueBuffer(mLockedBuffer.get(), fd);
mPostedBuffer = mLockedBuffer;
mLockedBuffer = 0;
return err;
}
Surface.queueBuffer
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
...
// 獲取Slot數(shù)組保存的buffer
int i = getSlotFromBufferLocked(buffer);
..
IGraphicBufferProducer::QueueBufferOutput output;
IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,
mTransform ^ mStickyTransform, fence, mStickyTransform,
mEnableFrameTimestamps);
...
// 插入buffer
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
...
// 通知
mQueueBufferCondition.broadcast();
return err;
}
// mSlog集合為按照順序保存GraphicBuffer的數(shù)組
int Surface::getSlotFromBufferLocked(android_native_buffer_t* buffer) const {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (mSlots[i].buffer != NULL && mSlots[i].buffer->handle == buffer->handle) {
return i;
}
}
return BAD_VALUE;
}
BufferQueueProducer.cpp.queueBuffer
根據(jù)輸入?yún)?shù)完善一個(gè)BufferItem乓旗,然后通知frameAvailabel
status_t BufferQueueProducer::queueBuffer(int slot, const QueueBufferInput &input, QueueBufferOutput *output) {
//從input中獲取一些列參數(shù)
input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
&crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
&getFrameTimestamps);
sp<IConsumerListener> frameAvailableListener;
sp<IConsumerListener> frameReplacedListener;
BufferItem item; //一個(gè)待渲染的幀
...
//item的一系列賦值操作
item.mAcquireCalled = mSlots[slot].mAcquireCalled;
item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; //根據(jù)slot獲取GraphicBuffer。
item.mCrop = crop;
item.mTransform = transform &
~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
item.mTransformToDisplayInverse =
(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
item.mScalingMode = static_cast<uint32_t>(scalingMode);
item.mTimestamp = requestedPresentTimestamp;
item.mIsAutoTimestamp = isAutoTimestamp;
...
if (frameAvailableListener != NULL) {
frameAvailableListener->onFrameAvailable(item); //item是一個(gè)frame集索,準(zhǔn)備完畢屿愚,要通知外界
} else if (frameReplacedListener != NULL) {
frameReplacedListener->onFrameReplaced(item);
}
addAndGetFrameTimestamps(&newFrameEventsEntry,etFrameTimestamps ? &output->frameTimestamps : nullptr);
return NO_ERROR;
}
BufferLayer.cpp
void BufferLayer::onFrameAvailable(const BufferItem& item) {
...
mFlinger->signalLayerUpdate();
}
SurfaceFlinger.cpp
執(zhí)行SurfaceFlinger的invalidate方法
void SurfaceFlinger::signalLayerUpdate() {
mEventQueue->invalidate();
}
————————————————————————————————————
推薦閱讀:圖形系統(tǒng)總結(jié)