The flow of the app to create the Surface
2016-01-18 20:22
661 查看
@ViewRootImpl.java
private void performTraversals()
{
relayoutResult =
relayoutWindow(params,viewVisibility, insetsPending);
}
@ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParamsparams, int viewVisibility,
boolean insetsPending)
{
int relayoutResult =
mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth()* appScale + 0.5f),
(int)(mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ?WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame,mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingStableInsets,mPendingConfiguration,
mSurface);
}
@out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IWindowSession.java
public static abstractclass Stub extends android.os.Binder implements android.view.IWindowSession
Override public boolean
onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags) throws android.os.RemoteException
{
case TRANSACTION_relayout:
{
data.enforceInterface(DESCRIPTOR);
android.view.IWindow _arg0;
_arg0 =android.view.IWindow.Stub.asInterface(data.readStrongBinder());
int _arg1;
_arg1 = data.readInt();
android.view.WindowManager.LayoutParams_arg2;
if ((0!=data.readInt())) {
_arg2 =android.view.WindowManager.LayoutParams.CREATOR.createFromParcel(data);
}
else {
_arg2 = null;
}
int _arg3;
_arg3 = data.readInt();
int _arg4;
_arg4 = data.readInt();
int _arg5;
_arg5 = data.readInt();
int _arg6;
_arg6 = data.readInt();
android.graphics.Rect _arg7;
_arg7 = new android.graphics.Rect();
android.graphics.Rect _arg8;
_arg8 = new android.graphics.Rect();
android.graphics.Rect _arg9;
_arg9 = new android.graphics.Rect();
android.graphics.Rect _arg10;
_arg10 = new android.graphics.Rect();
android.graphics.Rect _arg11;
_arg11 = new android.graphics.Rect();
android.content.res.Configuration _arg12;
_arg12 = newandroid.content.res.Configuration();
android.view.Surface _arg13;
_arg13 = new
android.view.Surface();
int _result =
this.relayout(_arg0,_arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11,_arg12, _arg13);
reply.writeNoException();
reply.writeInt(_result);
if ((_arg7!=null)) {
reply.writeInt(1);
_arg7.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg8!=null)) {
reply.writeInt(1);
_arg8.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg9!=null)) {
reply.writeInt(1);
_arg9.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg10!=null)) {
reply.writeInt(1);
_arg10.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg11!=null)) {
reply.writeInt(1);
_arg11.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg12!=null)) {
reply.writeInt(1);
_arg12.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg13!=null)) {
reply.writeInt(1);
_arg13.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
return true;
}
@Override public int
relayout(android.view.IWindow window, int seq,android.view.WindowManager.LayoutParams attrs, int requestedWidth, intrequestedHeight, int viewVisibility, int flags, android.graphics.Rect outFrame,android.graphics.Rect outOverscanInsets, android.graphics.RectoutContentInsets,
android.graphics.Rect outVisibleInsets, android.graphics.RectoutStableInsets, android.content.res.Configuration outConfig,
android.view.Surface outSurface) throwsandroid.os.RemoteException
{
android.os.Parcel _data =android.os.Parcel.obtain();
android.os.Parcel _reply =android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((window!=null))?(window.asBinder()):(null)));
_data.writeInt(seq);
if ((attrs!=null)) {
_data.writeInt(1);
attrs.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
_data.writeInt(requestedWidth);
_data.writeInt(requestedHeight);
_data.writeInt(viewVisibility);
_data.writeInt(flags);
mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
if ((0!=_reply.readInt())) {
outFrame.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outOverscanInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outContentInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outVisibleInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outStableInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outConfig.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outSurface.readFromParcel(_reply);
}
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Session.java
public int relayout(IWindow window,int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
Surface
outSurface){
int res =
mService.relayoutWindow(this, window, seq, attrs,
requestedWidth,requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets,outContentInsets, outVisibleInsets,
outStableInsets, outConfig,
outSurface);
if (false) Slog.d(WindowManagerService.TAG,"<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}
@WindowManagerService.java
public int relayoutWindow(Sessionsession, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
Surface outSurface)
{
SurfaceControl
surfaceControl = winAnimator.createSurfaceLocked();
outSurface.copyFrom(surfaceControl);
}
@WindowStateAnimator.java
SurfaceControl
createSurfaceLocked()
{
mSurfaceControl = new
SurfaceControl(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format,flags);
}
public SurfaceControl(SurfaceSessionsession,
String name, int w, int h, int format, int flags)
{
mNativeObject =
nativeCreate(session,name, w, h, format, flags);
}
@android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv*env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags) {
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient>client(android_view_SurfaceSession_getClient(env, sessionObj));
sp<SurfaceControl> surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);
if(surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
}
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
}
@SurfaceComposerClient.cpp
sp<SurfaceControl>
SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
sp<SurfaceControl> sur;
if(mStatus == NO_ERROR) {
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
status_t err = mClient->createSurface(name,w, h, format, flags,
&handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s",strerror(-err));
if (err == NO_ERROR) {
sur = new
SurfaceControl(this,handle, gbp);
}
}
return sur;
}
@ISurfaceComposerClient.cpp
virtual status_t
createSurface(constString8& name, uint32_t w,
uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
data.writeString8(name);
data.writeInt32(w);
data.writeInt32(h);
data.writeInt32(format);
data.writeInt32(flags);
remote()->transact(CREATE_SURFACE,data, &reply);
*handle = reply.readStrongBinder();
*gbp =interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
return reply.readInt32();
}
status_t BnSurfaceComposerClient::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
String8 name = data.readString8();
uint32_t w = data.readInt32();
uint32_t h = data.readInt32();
PixelFormat format = data.readInt32();
uint32_t flags = data.readInt32();
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
status_t result = createSurface(name, w, h, format, flags,
&handle, &gbp);
reply->writeStrongBinder(handle);
reply->writeStrongBinder(gbp->asBinder());
reply->writeInt32(result);
return NO_ERROR;
} break;
@SufaceFlinger::Client.cpp
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
/*
*createSurface must be called from the GL thread so that it can
*have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name,Client* client,
uint32_t w, uint32_t h, PixelFormatformat, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h),format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name,client, w, h, format, flags,
handle, gbp);
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get())->getResult();
}
@SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{
switch (flags &ISurfaceComposerClient::eFXSurfaceMask)
caseISurfaceComposerClient::eFXSurfaceNormal:
result =
createNormalLayer(client,
name, w, h, flags, format,
handle, gbp, &layer);
}
status_t SurfaceFlinger::createNormalLayer(constsp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags,PixelFormat& format,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,sp<Layer>* outLayer)
{
*outLayer =
newLayer(this, client, name, w, h, flags);
*gbp = (*outLayer)->getProducer();
}
@Layer.cpp
Layer::Layer(SurfaceFlinger* flinger, constsp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
: contentDirty(false),
sequence(uint32_t(android_atomic_inc(&sSequence))),
mFlinger(flinger),
mTextureName(-1U),
mPremultipliedAlpha(true),
mName("unnamed"),
mDebug(false),
mFormat(PIXEL_FORMAT_NONE),
mTransactionFlags(0),
mQueuedFrames(0),
mSidebandStreamChanged(false),
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
mRefreshPending(false),
mFrameLatencyNeeded(false),
mFiltering(false),
mNeedsFiltering(false),
mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
mSecure(false),
mProtectedByApp(false),
mHasSurface(false),
mClientRef(client),
mPotentialCursor(false),
mTransformHint(0)
{
}
//after new the Layer, it is extend toRefBase, so it would call the onFirstRef().
void Layer::onFirstRef(){
//Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer =
new MonitoredProducer(producer,mFlinger);
mSurfaceFlingerConsumer =
newSurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
}
@BufferQueue.cpp
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>*outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator) {
sp<BufferQueueCore>
core(newBufferQueueCore(allocator));
sp<IGraphicBufferProducer> producer(newBufferQueueProducer(core));
sp<IGraphicBufferConsumer> consumer(newBufferQueueConsumer(core));
*outProducer = producer;
*outConsumer = consumer;
}
@BufferQueueCore.cpp
BufferQueueCore::BufferQueueCore(constsp<IGraphicBufferAlloc>& allocator)
{
sp<ISurfaceComposer>composer(ComposerService::getComposerService());
mAllocator = composer->createGraphicBufferAlloc();
}
@ViewRootImpl.java
private void draw(booleanfullRedrawNeeded)
{
Surface surface = mSurface;//this get by
relayoutWindow(WindowManager.LayoutParams params,int viewVisibility, boolean insetsPending) @ViewRootImpl.java
drawSoftware(surface,mAttachInfo, xOffset, yOffset, scalingRequired, dirty);
}
private boolean
drawSoftware(Surfacesurface, AttachInfo attachInfo, int xoff, int yoff,
boolean scalingRequired, Rect dirty) {
{
canvas = mSurface.lockCanvas(dirty);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
mView.draw(canvas); //mView is set bysetView(View view, WindowManager.LayoutParams attrs, View panelParentView) , so mView is the mDecor
this is called by addView() @WindowManagerGlobal.java root.setView(view,wparams, panelParentView);// wm.addView(decor, l);
surface.unlockCanvasAndPost(canvas);
}
@Surface.java
public Canvas
lockCanvas(RectinOutDirty)
throws Surface.OutOfResourcesException, IllegalArgumentException {
synchronized (mLock) {
checkNotReleasedLocked();
if (mLockedObject != 0) {
// Ideally, nativeLockCanvas()would throw in this situation and prevent the
// double-lock, but that won'thappen if mNativeObject was updated. Wecan't
// abandon the oldmLockedObject because it might still be in use, so instead
// we just refuse to re-lockthe Surface.
throw newIllegalArgumentException("Surface was already locked");
}
mLockedObject =
nativeLockCanvas(mNativeObject,mCanvas, inOutDirty);
return mCanvas;
}
}
@android_view_Surface.cpp
static jlong nativeLockCanvas(JNIEnv*env, jclass clazz,
jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
{
sp<Surface>
surface(reinterpret_cast<Surface*>(nativeObject));
status_t err = surface->lock(&outBuffer,dirtyRectPtr);
env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat,outBuffer.format);
}
@Surface.cpp
Surface::Surface(
const sp<IGraphicBufferProducer>& bufferProducer,
bool controlledByApp)
:mGraphicBufferProducer(bufferProducer)
{
//Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval =hook_setSwapInterval;
ANativeWindow::dequeueBuffer =hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
ANativeWindow::queueBuffer =hook_queueBuffer;
ANativeWindow::query =hook_query;
ANativeWindow::perform =hook_perform;
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
mReqWidth = 0;
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mCrop.clear();
mDirtyRect.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mStickyTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
mProducerControlledByApp = controlledByApp;
mSwapIntervalZero = false;
}
status_t Surface::lock(ANativeWindow_Buffer*outBuffer, ARect* inOutDirtyBounds)
{
interr =
Surface::connect(NATIVE_WINDOW_API_CPU);
setUsage(GRALLOC_USAGE_SW_READ_OFTEN |GRALLOC_USAGE_SW_WRITE_OFTEN);
ANativeWindowBuffer* out;
int fenceFd = -1;
status_t err =
dequeueBuffer(&out, &fenceFd);
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
const Rect bounds(backBuffer->width, backBuffer->height);
int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
const bool canCopyBack = (frontBuffer != 0 &&
backBuffer->width == frontBuffer->width &&
backBuffer->height ==frontBuffer->height &&
backBuffer->format ==frontBuffer->format);
const Region copyback(oldDirtyRegion.subtract(newDirtyRegion));
if (!copyback.isEmpty())
copyBlt(backBuffer,frontBuffer, copyback);
void* vaddr;
status_t res = backBuffer->lockAsync(
GRALLOC_USAGE_SW_READ_OFTEN |GRALLOC_USAGE_SW_WRITE_OFTEN,
newDirtyRegion.bounds(),&vaddr, fenceFd);
mLockedBuffer = backBuffer;
outBuffer->width =backBuffer->width;
outBuffer->height = backBuffer->height;
outBuffer->stride = backBuffer->stride;
outBuffer->format = backBuffer->format;
outBuffer->bits = vaddr;
}
int Surface::connect(intapi) {
interr =
mGraphicBufferProducer->connect(listener,api, mProducerControlledByApp, &output);
}
status_tBnGraphicBufferProducer::onTransact(
uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
{
caseCONNECT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<IProducerListener> listener;
if (data.readInt32() == 1) {
listener =IProducerListener::asInterface(data.readStrongBinder());
}
int api = data.readInt32();
bool producerControlledByApp = data.readInt32();
QueueBufferOutput* const output =
reinterpret_cast<QueueBufferOutput*>(
reply->writeInplace(sizeof(QueueBufferOutput)));
status_t res =
connect(listener,api, producerControlledByApp, output);
reply->writeInt32(res);
return NO_ERROR;
}
@BufferQueueProducer.cpp
status_t BufferQueueProducer::connect(constsp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput *output) {
ATRACE_CALL();
{
switch (api) {
case NATIVE_WINDOW_API_EGL:
case
NATIVE_WINDOW_API_CPU:
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
mCore->mConnectedApi = api;
output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
mCore->mTransformHint,mCore->mQueue.size());
// Set up a death notification so that we can disconnect
// automatically if the remote producer dies
if (listener != NULL &&
listener->asBinder()->remoteBinder() != NULL) {
status =listener->asBinder()->linkToDeath(
static_cast<IBinder::DeathRecipient*>(this));
if (status != NO_ERROR) {
BQ_LOGE("connect(P):linkToDeath failed: %s (%d)",
strerror(-status),status);
}
}
mCore->mConnectedProducerListener =listener;
break;
}
@Surface.cpp
int Surface::dequeueBuffer(android_native_buffer_t**buffer, int* fenceFd) {
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
reqW, reqH, reqFormat, reqUsage);
result = mGraphicBufferProducer->requestBuffer(buf,&gbuf);
*fenceFd = fence->dup();
*buffer = gbuf.get();
}
@GraphicBuffer.cpp
status_t GraphicBuffer::lockAsync(uint32_tusage, const Rect& rect, void** vaddr, int fenceFd)
{
status_t res =
getBufferMapper().lockAsync(handle,usage, rect, vaddr, fenceFd);
}
@GraphicBufferMapper.cpp
status_t GraphicBufferMapper::lockAsync(buffer_handle_thandle,
int usage, const Rect& bounds, void** vaddr, int fenceFd)
{
if(mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3){
err =
mAllocMod->lockAsync(mAllocMod,handle, usage,
bounds.left, bounds.top,bounds.width(), bounds.height(),
vaddr,fenceFd);
}else {
sync_wait(fenceFd, -1);
close(fenceFd);
err =
mAllocMod->lock(mAllocMod,handle, usage,
bounds.left, bounds.top,bounds.width(), bounds.height(),
vaddr);
}
}
@Surface.java
public void unlockCanvasAndPost(Canvascanvas) {
synchronized (mLock) {
checkNotReleasedLocked();
if (mHwuiContext != null) {
mHwuiContext.unlockAndPost(canvas);
} else {
unlockSwCanvasAndPost(canvas);
}
}
}
private void unlockSwCanvasAndPost(Canvascanvas) {
nativeUnlockCanvasAndPost(mLockedObject,canvas);
}
@android_view_Surface.cpp
static void nativeUnlockCanvasAndPost(JNIEnv*env, jclass clazz,
jlong nativeObject, jobject canvasObj) {
sp<Surface>
surface(reinterpret_cast<Surface*>(nativeObject));
// detach the canvas from the surface
env->CallVoidMethod(canvasObj, gCanvasClassInfo.setNativeBitmap,(jlong)0);
//unlock surface
status_t err =
surface->unlockAndPost();
}
@Surface.cpp
status_t Surface::unlockAndPost()
{
status_t err =
mLockedBuffer->unlockAsync(&fd);
err= queueBuffer(mLockedBuffer.get(), fd);
}
int Surface::queueBuffer(android_native_buffer_t*buffer, int fenceFd) {
ATRACE_CALL();
{
status_t err =
mGraphicBufferProducer->queueBuffer(i,input, &output);
}
@BufferQueueProducer.cpp
status_t BufferQueueProducer::queueBuffer(intslot,
const QueueBufferInput &input, QueueBufferOutput *output) {
{
sp<IConsumerListener> frameAvailableListener;
frameAvailableListener= mCore->mConsumerListener; //this is done by connect() to setmCore->mConsumerListener = consumerListener;
frameAvailableListener->onFrameAvailable(item);//
}
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
const android::BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
if(listener != NULL) {
listener->onFrameAvailable(item); //
}
}
void Layer::onFrameAvailable(constBufferItem& item) {
//Add this buffer from our internal queue tracker
{// Autolock scope
Mutex::Autolock lock(mQueueItemLock);
mQueueItems.push_back(item);
}
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
private void performTraversals()
{
relayoutResult =
relayoutWindow(params,viewVisibility, insetsPending);
}
@ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParamsparams, int viewVisibility,
boolean insetsPending)
{
int relayoutResult =
mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth()* appScale + 0.5f),
(int)(mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ?WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame,mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingStableInsets,mPendingConfiguration,
mSurface);
}
@out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IWindowSession.java
public static abstractclass Stub extends android.os.Binder implements android.view.IWindowSession
Override public boolean
onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags) throws android.os.RemoteException
{
case TRANSACTION_relayout:
{
data.enforceInterface(DESCRIPTOR);
android.view.IWindow _arg0;
_arg0 =android.view.IWindow.Stub.asInterface(data.readStrongBinder());
int _arg1;
_arg1 = data.readInt();
android.view.WindowManager.LayoutParams_arg2;
if ((0!=data.readInt())) {
_arg2 =android.view.WindowManager.LayoutParams.CREATOR.createFromParcel(data);
}
else {
_arg2 = null;
}
int _arg3;
_arg3 = data.readInt();
int _arg4;
_arg4 = data.readInt();
int _arg5;
_arg5 = data.readInt();
int _arg6;
_arg6 = data.readInt();
android.graphics.Rect _arg7;
_arg7 = new android.graphics.Rect();
android.graphics.Rect _arg8;
_arg8 = new android.graphics.Rect();
android.graphics.Rect _arg9;
_arg9 = new android.graphics.Rect();
android.graphics.Rect _arg10;
_arg10 = new android.graphics.Rect();
android.graphics.Rect _arg11;
_arg11 = new android.graphics.Rect();
android.content.res.Configuration _arg12;
_arg12 = newandroid.content.res.Configuration();
android.view.Surface _arg13;
_arg13 = new
android.view.Surface();
int _result =
this.relayout(_arg0,_arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11,_arg12, _arg13);
reply.writeNoException();
reply.writeInt(_result);
if ((_arg7!=null)) {
reply.writeInt(1);
_arg7.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg8!=null)) {
reply.writeInt(1);
_arg8.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg9!=null)) {
reply.writeInt(1);
_arg9.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg10!=null)) {
reply.writeInt(1);
_arg10.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg11!=null)) {
reply.writeInt(1);
_arg11.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg12!=null)) {
reply.writeInt(1);
_arg12.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
if ((_arg13!=null)) {
reply.writeInt(1);
_arg13.writeToParcel(reply,android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
return true;
}
@Override public int
relayout(android.view.IWindow window, int seq,android.view.WindowManager.LayoutParams attrs, int requestedWidth, intrequestedHeight, int viewVisibility, int flags, android.graphics.Rect outFrame,android.graphics.Rect outOverscanInsets, android.graphics.RectoutContentInsets,
android.graphics.Rect outVisibleInsets, android.graphics.RectoutStableInsets, android.content.res.Configuration outConfig,
android.view.Surface outSurface) throwsandroid.os.RemoteException
{
android.os.Parcel _data =android.os.Parcel.obtain();
android.os.Parcel _reply =android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((window!=null))?(window.asBinder()):(null)));
_data.writeInt(seq);
if ((attrs!=null)) {
_data.writeInt(1);
attrs.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
_data.writeInt(requestedWidth);
_data.writeInt(requestedHeight);
_data.writeInt(viewVisibility);
_data.writeInt(flags);
mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
if ((0!=_reply.readInt())) {
outFrame.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outOverscanInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outContentInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outVisibleInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outStableInsets.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outConfig.readFromParcel(_reply);
}
if ((0!=_reply.readInt())) {
outSurface.readFromParcel(_reply);
}
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Session.java
public int relayout(IWindow window,int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
Surface
outSurface){
int res =
mService.relayoutWindow(this, window, seq, attrs,
requestedWidth,requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets,outContentInsets, outVisibleInsets,
outStableInsets, outConfig,
outSurface);
if (false) Slog.d(WindowManagerService.TAG,"<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}
@WindowManagerService.java
public int relayoutWindow(Sessionsession, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
Surface outSurface)
{
SurfaceControl
surfaceControl = winAnimator.createSurfaceLocked();
outSurface.copyFrom(surfaceControl);
}
@WindowStateAnimator.java
SurfaceControl
createSurfaceLocked()
{
mSurfaceControl = new
SurfaceControl(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format,flags);
}
public SurfaceControl(SurfaceSessionsession,
String name, int w, int h, int format, int flags)
{
mNativeObject =
nativeCreate(session,name, w, h, format, flags);
}
@android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv*env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags) {
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient>client(android_view_SurfaceSession_getClient(env, sessionObj));
sp<SurfaceControl> surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);
if(surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
}
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
}
@SurfaceComposerClient.cpp
sp<SurfaceControl>
SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
sp<SurfaceControl> sur;
if(mStatus == NO_ERROR) {
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
status_t err = mClient->createSurface(name,w, h, format, flags,
&handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s",strerror(-err));
if (err == NO_ERROR) {
sur = new
SurfaceControl(this,handle, gbp);
}
}
return sur;
}
@ISurfaceComposerClient.cpp
virtual status_t
createSurface(constString8& name, uint32_t w,
uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
data.writeString8(name);
data.writeInt32(w);
data.writeInt32(h);
data.writeInt32(format);
data.writeInt32(flags);
remote()->transact(CREATE_SURFACE,data, &reply);
*handle = reply.readStrongBinder();
*gbp =interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
return reply.readInt32();
}
status_t BnSurfaceComposerClient::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
String8 name = data.readString8();
uint32_t w = data.readInt32();
uint32_t h = data.readInt32();
PixelFormat format = data.readInt32();
uint32_t flags = data.readInt32();
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
status_t result = createSurface(name, w, h, format, flags,
&handle, &gbp);
reply->writeStrongBinder(handle);
reply->writeStrongBinder(gbp->asBinder());
reply->writeInt32(result);
return NO_ERROR;
} break;
@SufaceFlinger::Client.cpp
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
/*
*createSurface must be called from the GL thread so that it can
*have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name,Client* client,
uint32_t w, uint32_t h, PixelFormatformat, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h),format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name,client, w, h, format, flags,
handle, gbp);
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get())->getResult();
}
@SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{
switch (flags &ISurfaceComposerClient::eFXSurfaceMask)
caseISurfaceComposerClient::eFXSurfaceNormal:
result =
createNormalLayer(client,
name, w, h, flags, format,
handle, gbp, &layer);
}
status_t SurfaceFlinger::createNormalLayer(constsp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags,PixelFormat& format,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,sp<Layer>* outLayer)
{
*outLayer =
newLayer(this, client, name, w, h, flags);
*gbp = (*outLayer)->getProducer();
}
@Layer.cpp
Layer::Layer(SurfaceFlinger* flinger, constsp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
: contentDirty(false),
sequence(uint32_t(android_atomic_inc(&sSequence))),
mFlinger(flinger),
mTextureName(-1U),
mPremultipliedAlpha(true),
mName("unnamed"),
mDebug(false),
mFormat(PIXEL_FORMAT_NONE),
mTransactionFlags(0),
mQueuedFrames(0),
mSidebandStreamChanged(false),
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
mRefreshPending(false),
mFrameLatencyNeeded(false),
mFiltering(false),
mNeedsFiltering(false),
mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
mSecure(false),
mProtectedByApp(false),
mHasSurface(false),
mClientRef(client),
mPotentialCursor(false),
mTransformHint(0)
{
}
//after new the Layer, it is extend toRefBase, so it would call the onFirstRef().
void Layer::onFirstRef(){
//Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer =
new MonitoredProducer(producer,mFlinger);
mSurfaceFlingerConsumer =
newSurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
}
@BufferQueue.cpp
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>*outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator) {
sp<BufferQueueCore>
core(newBufferQueueCore(allocator));
sp<IGraphicBufferProducer> producer(newBufferQueueProducer(core));
sp<IGraphicBufferConsumer> consumer(newBufferQueueConsumer(core));
*outProducer = producer;
*outConsumer = consumer;
}
@BufferQueueCore.cpp
BufferQueueCore::BufferQueueCore(constsp<IGraphicBufferAlloc>& allocator)
{
sp<ISurfaceComposer>composer(ComposerService::getComposerService());
mAllocator = composer->createGraphicBufferAlloc();
}
@ViewRootImpl.java
private void draw(booleanfullRedrawNeeded)
{
Surface surface = mSurface;//this get by
relayoutWindow(WindowManager.LayoutParams params,int viewVisibility, boolean insetsPending) @ViewRootImpl.java
drawSoftware(surface,mAttachInfo, xOffset, yOffset, scalingRequired, dirty);
}
private boolean
drawSoftware(Surfacesurface, AttachInfo attachInfo, int xoff, int yoff,
boolean scalingRequired, Rect dirty) {
{
canvas = mSurface.lockCanvas(dirty);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
mView.draw(canvas); //mView is set bysetView(View view, WindowManager.LayoutParams attrs, View panelParentView) , so mView is the mDecor
this is called by addView() @WindowManagerGlobal.java root.setView(view,wparams, panelParentView);// wm.addView(decor, l);
surface.unlockCanvasAndPost(canvas);
}
@Surface.java
public Canvas
lockCanvas(RectinOutDirty)
throws Surface.OutOfResourcesException, IllegalArgumentException {
synchronized (mLock) {
checkNotReleasedLocked();
if (mLockedObject != 0) {
// Ideally, nativeLockCanvas()would throw in this situation and prevent the
// double-lock, but that won'thappen if mNativeObject was updated. Wecan't
// abandon the oldmLockedObject because it might still be in use, so instead
// we just refuse to re-lockthe Surface.
throw newIllegalArgumentException("Surface was already locked");
}
mLockedObject =
nativeLockCanvas(mNativeObject,mCanvas, inOutDirty);
return mCanvas;
}
}
@android_view_Surface.cpp
static jlong nativeLockCanvas(JNIEnv*env, jclass clazz,
jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
{
sp<Surface>
surface(reinterpret_cast<Surface*>(nativeObject));
status_t err = surface->lock(&outBuffer,dirtyRectPtr);
env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat,outBuffer.format);
}
@Surface.cpp
Surface::Surface(
const sp<IGraphicBufferProducer>& bufferProducer,
bool controlledByApp)
:mGraphicBufferProducer(bufferProducer)
{
//Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval =hook_setSwapInterval;
ANativeWindow::dequeueBuffer =hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
ANativeWindow::queueBuffer =hook_queueBuffer;
ANativeWindow::query =hook_query;
ANativeWindow::perform =hook_perform;
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
mReqWidth = 0;
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mCrop.clear();
mDirtyRect.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mStickyTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
mProducerControlledByApp = controlledByApp;
mSwapIntervalZero = false;
}
status_t Surface::lock(ANativeWindow_Buffer*outBuffer, ARect* inOutDirtyBounds)
{
interr =
Surface::connect(NATIVE_WINDOW_API_CPU);
setUsage(GRALLOC_USAGE_SW_READ_OFTEN |GRALLOC_USAGE_SW_WRITE_OFTEN);
ANativeWindowBuffer* out;
int fenceFd = -1;
status_t err =
dequeueBuffer(&out, &fenceFd);
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
const Rect bounds(backBuffer->width, backBuffer->height);
int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
const bool canCopyBack = (frontBuffer != 0 &&
backBuffer->width == frontBuffer->width &&
backBuffer->height ==frontBuffer->height &&
backBuffer->format ==frontBuffer->format);
const Region copyback(oldDirtyRegion.subtract(newDirtyRegion));
if (!copyback.isEmpty())
copyBlt(backBuffer,frontBuffer, copyback);
void* vaddr;
status_t res = backBuffer->lockAsync(
GRALLOC_USAGE_SW_READ_OFTEN |GRALLOC_USAGE_SW_WRITE_OFTEN,
newDirtyRegion.bounds(),&vaddr, fenceFd);
mLockedBuffer = backBuffer;
outBuffer->width =backBuffer->width;
outBuffer->height = backBuffer->height;
outBuffer->stride = backBuffer->stride;
outBuffer->format = backBuffer->format;
outBuffer->bits = vaddr;
}
int Surface::connect(intapi) {
interr =
mGraphicBufferProducer->connect(listener,api, mProducerControlledByApp, &output);
}
status_tBnGraphicBufferProducer::onTransact(
uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
{
caseCONNECT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<IProducerListener> listener;
if (data.readInt32() == 1) {
listener =IProducerListener::asInterface(data.readStrongBinder());
}
int api = data.readInt32();
bool producerControlledByApp = data.readInt32();
QueueBufferOutput* const output =
reinterpret_cast<QueueBufferOutput*>(
reply->writeInplace(sizeof(QueueBufferOutput)));
status_t res =
connect(listener,api, producerControlledByApp, output);
reply->writeInt32(res);
return NO_ERROR;
}
@BufferQueueProducer.cpp
status_t BufferQueueProducer::connect(constsp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput *output) {
ATRACE_CALL();
{
switch (api) {
case NATIVE_WINDOW_API_EGL:
case
NATIVE_WINDOW_API_CPU:
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
mCore->mConnectedApi = api;
output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
mCore->mTransformHint,mCore->mQueue.size());
// Set up a death notification so that we can disconnect
// automatically if the remote producer dies
if (listener != NULL &&
listener->asBinder()->remoteBinder() != NULL) {
status =listener->asBinder()->linkToDeath(
static_cast<IBinder::DeathRecipient*>(this));
if (status != NO_ERROR) {
BQ_LOGE("connect(P):linkToDeath failed: %s (%d)",
strerror(-status),status);
}
}
mCore->mConnectedProducerListener =listener;
break;
}
@Surface.cpp
int Surface::dequeueBuffer(android_native_buffer_t**buffer, int* fenceFd) {
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
reqW, reqH, reqFormat, reqUsage);
result = mGraphicBufferProducer->requestBuffer(buf,&gbuf);
*fenceFd = fence->dup();
*buffer = gbuf.get();
}
@GraphicBuffer.cpp
status_t GraphicBuffer::lockAsync(uint32_tusage, const Rect& rect, void** vaddr, int fenceFd)
{
status_t res =
getBufferMapper().lockAsync(handle,usage, rect, vaddr, fenceFd);
}
@GraphicBufferMapper.cpp
status_t GraphicBufferMapper::lockAsync(buffer_handle_thandle,
int usage, const Rect& bounds, void** vaddr, int fenceFd)
{
if(mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3){
err =
mAllocMod->lockAsync(mAllocMod,handle, usage,
bounds.left, bounds.top,bounds.width(), bounds.height(),
vaddr,fenceFd);
}else {
sync_wait(fenceFd, -1);
close(fenceFd);
err =
mAllocMod->lock(mAllocMod,handle, usage,
bounds.left, bounds.top,bounds.width(), bounds.height(),
vaddr);
}
}
@Surface.java
public void unlockCanvasAndPost(Canvascanvas) {
synchronized (mLock) {
checkNotReleasedLocked();
if (mHwuiContext != null) {
mHwuiContext.unlockAndPost(canvas);
} else {
unlockSwCanvasAndPost(canvas);
}
}
}
private void unlockSwCanvasAndPost(Canvascanvas) {
nativeUnlockCanvasAndPost(mLockedObject,canvas);
}
@android_view_Surface.cpp
static void nativeUnlockCanvasAndPost(JNIEnv*env, jclass clazz,
jlong nativeObject, jobject canvasObj) {
sp<Surface>
surface(reinterpret_cast<Surface*>(nativeObject));
// detach the canvas from the surface
env->CallVoidMethod(canvasObj, gCanvasClassInfo.setNativeBitmap,(jlong)0);
//unlock surface
status_t err =
surface->unlockAndPost();
}
@Surface.cpp
status_t Surface::unlockAndPost()
{
status_t err =
mLockedBuffer->unlockAsync(&fd);
err= queueBuffer(mLockedBuffer.get(), fd);
}
int Surface::queueBuffer(android_native_buffer_t*buffer, int fenceFd) {
ATRACE_CALL();
{
status_t err =
mGraphicBufferProducer->queueBuffer(i,input, &output);
}
@BufferQueueProducer.cpp
status_t BufferQueueProducer::queueBuffer(intslot,
const QueueBufferInput &input, QueueBufferOutput *output) {
{
sp<IConsumerListener> frameAvailableListener;
frameAvailableListener= mCore->mConsumerListener; //this is done by connect() to setmCore->mConsumerListener = consumerListener;
frameAvailableListener->onFrameAvailable(item);//
}
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
const android::BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
if(listener != NULL) {
listener->onFrameAvailable(item); //
}
}
void Layer::onFrameAvailable(constBufferItem& item) {
//Add this buffer from our internal queue tracker
{// Autolock scope
Mutex::Autolock lock(mQueueItemLock);
mQueueItems.push_back(item);
}
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
相关文章推荐
- Android工程目录结构及基本常用框架
- Android笔记--layout_gravity和gravity,src和background,fragment和fragmentactivity的理解
- android把view设置成透明
- Ios xcode快捷键
- 实现应用WebView组件加载使用HTML代码添加的帮助信息
- iOS——button&&imageview的学习笔记
- 通过addDataScheme("file") 浅析android事件过滤策略
- iOS 本地数据持久化 中UserDefault的使用
- Unity学习笔记之UGUI模块RectTransform的变换推导
- 在Android中显示gif图片
- iOS 简易无限滚动的图片轮播器 Demo事例
- 关于Android studio混淆遇到的问题
- 实现应用WebView组件浏览指定网页
- swift 标准库
- 【Android界面实现】使用Canvas对象实现“刮刮乐”效果
- Andorid开发——ListView
- iOS推送与角标总结
- MTK Android手机进程列表
- Android 中编译版本,最小版本, 目标版本都有什么区别?
- ios 中如何处理于Webview 的交互