Indicate the source and author's contact information during reprinting.
Article Source: http://www.limodev.cn/blog
Author contact: Li xianjing <xianjimli@gmail.com>
Android GUI update process
Related Components
1. viewroot
In private void draw (Boolean
In fullredrawneeded), lockcanvas is called to obtain a canvas object, and the draw function of the sub-window (View) is called recursively.
Draw yourself, and finally call unlockcanvasandpost to let the surface update itself to the screen.
canvas = surface.lockCanvas(dirty);mView.draw(canvas);surface.unlockCanvasAndPost(canvas);
2. Android/View/Surface
It mainly encapsulates some native functions.
private native Canvas lockCanvasNative(Rect dirty); public native void unlockCanvasAndPost(Canvas canvas);
3. android_view_surface.cpp
This is the implementation of native functions.
Surface_lockcanvas First locks the surface to obtain information about the surface, such as the format, width, height, and Pixel Buffer. Then create a bitmap, which shares a pixel buffer, so that the view can directly draw itself to the surface.
status_t err = surface->lock(&info, &dirtyRegion);bitmap.setPixels(info.bits);nativeCanvas->setBitmapDevice(bitmap);
Surface_unlockcanvasandpost it disconnects the relationship between the skcanvas and the surface, and then calls the surface's unlockandpost.
nativeCanvas->setBitmapDevice(SkBitmap());status_t err = surface->unlockAndPost();
4. surfaceflinger_client/surface. cpp
Surface: Lock call dequeuebuffer to obtain an available buffer. dequeuebuffer calls sharedbufferclient: dequeue to wait until the backbuffer is available, lock the buffer and fill in relevant information.
status_t err = dequeueBuffer(&backBuffer);err = lockBuffer(backBuffer.get());
Surface: unlockandpost first unlock buffer, then call queuebuffer to display buffer.
status_t err = mLockedBuffer->unlock();err = queueBuffer(mLockedBuffer.get());
Surface: queuebuffer is interesting. It sets the updated region and notifies the server (surfaceflinger ).
mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);err = mSharedBufferClient->queue(bufIdx);client->signalServer();
Send a request to the service using the binder:
virtual void signal() const { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY); }
5. surfaceflinger
BnSurfaceComposer::onTransact case SIGNAL: { CHECK_INTERFACE(ISurfaceComposer, data, reply); signal(); } break;
This is the code for processing signal in surfaceflinger. It calls surfaceflinger: signal and then calls
Surfaceflinger: signalevent, and finally call messagequeue: invalidate to wake up
The main loop of surfaceflinger.
In the main loop, waitforevent is returned, and handlerepaint is used to synthesize a layer/surface.
bool SurfaceFlinger::threadLoop(){ waitForEvent(); handleRepaint(); postFramebuffer();}
Surfaceflinger: handlerepaint will call composesurfaces to merge the surfaces to be drawn and draw them to the backbuffer of framebuffer.
for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer = layers[i]; const Region& visibleRegion(layer->visibleRegionScreen); if (!visibleRegion.isEmpty()) { /* broncho cy add */#ifdef USEOVERLAY mToppest[1] = mToppest[0]; mToppest[0] = layer->getIdentity();#endif /* broncho end */ const Region clip(dirty.intersect(visibleRegion)); if (!clip.isEmpty()) { layer->draw(clip); } } }
Surfaceflinger: postframebuffer finally displays the buffer of framebuffer on the screen:
hw.flip(mInvalidRegion); -->eglSwapBuffers(dpy, surface);
The specific display process of framebuffer. Write it again next time.