Android6.0 SurfaceControl分析(一)SurfaceControl创建&使用 Surface创建&使用

原创 2017年03月22日 18:49:15

一、SurfaceControl的创建

SurfaceControl的创建是在ViewRootImpl中调用requestLayout,最后到WMS的relayoutWindow函数创建SurfaceControl对象。是通过WindowState的WindowStateAnimator对象调用createSurfaceLocked对象创建的。最后再通过outSurface传给ViewRootImpl。

                    ......
                    SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();//创建SurfaceControl
                    if (surfaceControl != null) {
                        outSurface.copyFrom(surfaceControl);//把Surface传给ViewRootImpl
                        if (SHOW_TRANSACTIONS) Slog.i(TAG,
                                "  OUT SURFACE " + outSurface + ": copied");
                    } else {
                        // For some reason there isn't a surface.  Clear the
                        // caller's object so they see the same state.
                        outSurface.release();
                    }
                    ......

然后在WindowStateAnimator的createSurfaceLocked中创建SurfaceControl,如下

                    mSurfaceControl = new SurfaceControl(
                        mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        width, height, format, flags);

随后会调用SurfaceControl的设置位置,设置layer等函数,这个我们后面再分析。

            SurfaceControl.openTransaction();
            try {
                mSurfaceX = left;
                mSurfaceY = top;

                try {
                    mSurfaceControl.setPosition(left, top);
                    mSurfaceLayer = mAnimLayer;
                    final DisplayContent displayContent = w.getDisplayContent();
                    if (displayContent != null) {
                        mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
                    }
                    mSurfaceControl.setLayer(mAnimLayer);
                    mSurfaceControl.setAlpha(0);
                    mSurfaceShown = false;
                } catch (RuntimeException e) {
                    Slog.w(TAG, "Error creating surface in " + w, e);
                    mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
                }
                mLastHidden = true;
            } finally {
                SurfaceControl.closeTransaction();
                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                        "<<< CLOSE TRANSACTION createSurfaceLocked");
            }

我们再来看看SurfaceControl的构造函数,这里主要是调用了nativeCreate函数来获取mNativeObject对象

    public SurfaceControl(SurfaceSession session,
            String name, int w, int h, int format, int flags)
                    throws OutOfResourcesException {
        ......
        mName = name;
        mNativeObject = nativeCreate(session, name, w, h, format, flags);
        if (mNativeObject == 0) {
            throw new OutOfResourcesException(
                    "Couldn't allocate SurfaceControl native object");
        }

        mCloseGuard.open("release");
    }

我们再看nativeCreate函数中,主要就是利用传下来的SurfaceSession对象获取client,然后调用createSurface。最后将创建的Surface对象返回,保存在SurfaceControl的mNativeObject对象中。这里的session就是WindowState的Session对象的SurfaceSession对象,而这个对象就是保存着和SurfaceFlinger通信的client对象。

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());
}

这里创建的SurfaceControl native层是在SurfaceComposerClient中createSurface函数中创建的,这里通过mClient连接SurfaceFlinger获取handle和gbp,然后创建SurfaceControl对象。这个SurfaceControl才是最终在java层的SurfaceControl的nativeObject对象。

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;
}

之前博客分析过创建WindowState的过程,会在addWindow中创建WindowState,然后调用其attach函数。WindowState的Session是保存和应用ViewRootImpl通信的Session对象。我们直接来看下WindowState的attach函数。

    void attach() {
        if (WindowManagerService.localLOGV) Slog.v(
            TAG, "Attaching " + this + " token=" + mToken
            + ", list=" + mToken.windows);
        mSession.windowAddedLocked();
    }

在Session的windowAddedLocked函数中创建了SurfaceSession对象。

    void windowAddedLocked() {
        if (mSurfaceSession == null) {
            if (WindowManagerService.localLOGV) Slog.v(
                WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
            mSurfaceSession = new SurfaceSession();
            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
                    WindowManagerService.TAG, "  NEW SURFACE SESSION " + mSurfaceSession);
            mService.mSessions.add(this);
            if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
                mService.dispatchNewAnimatorScaleLocked(this);
            }
        }
        mNumWindow++;
    }

SurfaceSession对象的构造函数就调用了nativeCreate函数,返回值保存在mNativeClient中了。

    public SurfaceSession() {
        mNativeClient = nativeCreate();
    }

这里的nativeCreate是在android_view_SurfaceSession.cpp中的jni函数,这里就是创建了SurfaceComposerClient对象,然后保存在了java层SurfaceSession的mNativeClient中了。

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}

在SurfaceComposerClient::onFirstRef函数中(就是在对象新建之前会调用这个函数),里面调用了ComposerService的createConnection 并且把返回值存入mClient对象。这个对象就是连接SurfaceFlinger的client对象。

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}
而最终ComposerService的connectLocked函数返回是连接SurfaceFlinger进程的client端的binder。
void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}

/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
        ALOGD("ComposerService reconnected");
    }
    return instance.mComposerService;
}

我们再来回顾WMS中relayout 把Surface传给应用ViewRootImpl,是调用了如下函数。是Surface对象的copyFrom函数

outSurface.copyFrom(surfaceControl);

这里我们调用了native函数nativeCreateFromSurfaceControl重新获取一个一个native对象,最后再调用Surface的setNativeObjectLocked函数保存在Surface对象的mNativeObject中。

    public void copyFrom(SurfaceControl other) {
        if (other == null) {
            throw new IllegalArgumentException("other must not be null");
        }

        long surfaceControlPtr = other.mNativeObject;
        if (surfaceControlPtr == 0) {
            throw new NullPointerException(
                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
        }
        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);//传入的参数是native层的SurfaceControl

        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);
        }
    }

nativeCreateFromSurfaceControl函数就是从native层的SurfaceControl对象调用getSurface对象,然后返回保存在Surface java对象的mNativeObject中。

static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong surfaceControlNativeObj) {
    /*
     * This is used by the WindowManagerService just after constructing
     * a Surface and is necessary for returning the Surface reference to
     * the caller. At this point, we should only have a SurfaceControl.
     */

    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
    return reinterpret_cast<jlong>(surface.get());
}

最终调用了SurfaceControl的getSurface,之前在SurfaceComposerClient中连接SurfaceFlinger时把gbp,传入了SurfaceControl。这里就是创建Surface使用。

sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) {
        // This surface is always consumed by SurfaceFlinger, so the
        // producerControlledByApp value doesn't matter; using false.
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

因此最后就很明显,WMS中有些窗口需要设置属性、大小、Z轴等最后调用的是SurfaceControl.cpp,而应用申请buffer等是调用Surface.cpp。这样就把WMS和ViewRootImpl分开了。


二、Surface和SurfaceControl的native层

上面说到WMS的窗口设置属性和应用的ViewRootImpl最后是通过SurfaceControl和Surface的native层和SurfaceFlinger通信的。

2.1 SurfaceControl

我们先来看SurfaceControl的,以下面例子为例:

    public void setLayer(int zorder) {
        checkNotReleased();
        nativeSetLayer(mNativeObject, zorder);
    }
然后到android_view_SurfaceControl.cpp的nativeSetLayer,最后就是调用保存在SurfaceControl java层的mNativeObjcet(这个就是native层的SurfaceControl)。因此最后是调用了SurfaceControl native的setLayer
static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) {
    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    status_t err = ctrl->setLayer(zorder);
    if (err < 0 && err != NO_INIT) {
        doThrowIAE(env);
    }
}

SurfaceControl中setLayer是调用了SurfaceComposerClient的setLayer函数,在SurfaceComposerClient::setLayer又是调用了Composer的setLayer函数

status_t SurfaceControl::setLayer(uint32_t layer) {
    status_t err = validate();
    if (err < 0) return err;
    return mClient->setLayer(mHandle, layer);
}
status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, uint32_t z) {
    return getComposer().setLayer(this, id, z);
}

这里最后调用Composer的setLayer函数,这里通过getLayerStateLocked获取到对应layer的state。像position,size等都是通过这个函数获取其layer的state,然后再修改其相关值。

status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
        const sp<IBinder>& id, uint32_t z) {
    Mutex::Autolock _l(mLock);
    layer_state_t* s = getLayerStateLocked(client, id);
    if (!s)
        return BAD_INDEX;
    s->what |= layer_state_t::eLayerChanged;
    s->z = z;
    return NO_ERROR;
}
我们来看getLayerStateLocked就是获取相关的ComposerState,Composer把所有的Layer的state都放在mComposerStates中。
layer_state_t* Composer::getLayerStateLocked(
        const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {

    ComposerState s;
    s.client = client->mClient;
    s.state.surface = id;

    ssize_t index = mComposerStates.indexOf(s);
    if (index < 0) {
        // we don't have it, add an initialized layer_state to our list
        index = mComposerStates.add(s);//没有这个layer,把它添加到mComposerStates中
    }

    ComposerState* const out = mComposerStates.editArray();
    return &(out[index].state);
}

这里我们不得不提下,整个SurfaceFlinger和SystemServer通信就一个ComposerService,因为它是单例。但是SurfaceControl有很多,每个窗口都有一个。但是最后所有的SurfaceControl都要在这里ComposerService和SurfaceFlinger通信,因此在mComposerStates中保存了所有layer的state。是通过SurfaceControl的openTransaction开启closeTransaction结束。然后一把和SurfaceFlinger通信,避免频繁通信造成效率下降。(具体我们下篇博客分析),但是比如我们createSurface是每个SurfaceComposerClient自己通过mClient和SurfaceFlinger通信,创建一个layer的。


我们再来看SurfaceComposerClient的onFirstRef函数,是调用了SurfaceFlinger的createConnection,然后保存在了自己的mClient中。这个mClient就是每个SurfaceControl用来和SurfaceFlinger通信的。

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

我们再来看看SurfaceFlinger的createConnection函数,就是新建了一个Client对象。这个对象是一个Binder的server端。

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}

这个Client的createSurface就是调用了SurfaceFlinger的createLayer,然后创建一个layer。这个layer主要是一个handle和一个gbp对象。

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, PixelFormat format, 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();
}

这个client对象就是用来创建Surface,销毁Surface,获取和清除Surface信息。

2.2 Surface

下面我们再来看java层的Surface,看lockCanvas函数。最后是调用了nativeLockCanvas函数

    public Canvas lockCanvas(Rect inOutDirty)
            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't happen if mNativeObject was updated.  We can't
                // abandon the old mLockedObject because it might still be in use, so instead
                // we just refuse to re-lock the Surface.
                throw new IllegalArgumentException("Surface was already locked");
            }
            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
            return mCanvas;
        }
    }

我们再来看android_view_Surface.cpp的nativeLockCanvas函数,先是调用Surface的lock函数,这个函数会从SurfaceFlinger中申请buffer,然后

static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));

    if (!isSurfaceValid(surface)) {
        doThrowIAE(env);
        return 0;
    }

    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;
    }

    ANativeWindow_Buffer outBuffer;
    status_t err = surface->lock(&outBuffer, dirtyRectPtr);//会从SurfaceFlinger中申请buffer
    if (err < 0) {
        const char* const exception = (err == NO_MEMORY) ?
                OutOfResourcesException :
                "java/lang/IllegalArgumentException";
        jniThrowException(env, exception, NULL);
        return 0;
    }

    SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
                                         convertPixelFormat(outBuffer.format),
                                         kPremul_SkAlphaType);
    if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
        info.fAlphaType = kOpaque_SkAlphaType;
    }

    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);
    }

    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(bitmap);

    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的lock函数中会调用dequeueBuffer函数,这个函数会通过mGraphicBufferProducer的dequeueBuffer函数来申请buffer

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ATRACE_CALL();
    ALOGV("Surface::dequeueBuffer");

    uint32_t reqWidth;
    uint32_t reqHeight;
    bool swapIntervalZero;
    PixelFormat reqFormat;
    uint32_t reqUsage;

    {
        Mutex::Autolock lock(mMutex);

        reqWidth = mReqWidth ? mReqWidth : mUserWidth;
        reqHeight = mReqHeight ? mReqHeight : mUserHeight;

        swapIntervalZero = mSwapIntervalZero;
        reqFormat = mReqFormat;
        reqUsage = mReqUsage;
    } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer

    int buf = -1;
    sp<Fence> fence;
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
            reqWidth, reqHeight, reqFormat, reqUsage);

    if (result < 0) {
        ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d, %d)"
             "failed: %d", swapIntervalZero, reqWidth, reqHeight, reqFormat,
             reqUsage, result);
        return result;
    }

    Mutex::Autolock lock(mMutex);

    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);

    // this should never happen
    ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);

    if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
        freeAllBuffers();
    }

    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        if (result != NO_ERROR) {
            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
            mGraphicBufferProducer->cancelBuffer(buf, fence);
            return result;
        }
    }

    if (fence->isValid()) {
        *fenceFd = fence->dup();
        if (*fenceFd == -1) {
            ALOGE("dequeueBuffer: error duping fence: %d", errno);
            // dup() should never fail; something is badly wrong. Soldier on
            // and hope for the best; the worst that should happen is some
            // visible corruption that lasts until the next frame.
        }
    } else {
        *fenceFd = -1;
    }

    *buffer = gbuf.get();
    return OK;
}


三、总结

这样我们很明显,应用申请buffer和窗口设置属性等完全分开来了。应用ViewRootImpl申请buffer通过Surface、窗口在WMS中通过SurfaceControl设置属性、Z轴、大小(通过openTransaction和closeTransaction开启关闭,因为设置窗口属性是所有窗口一起设置,然后通过ComposerService和SurfaceFlinger连接一起设置过去)。而在创建SurfaceComposerClient时,会和SurfaceFlinger通信调用一个createConnection函数,然后SurfaceFlinger那边会创建一个Client对象(Binder的server端),这样每个SurfaceComposerClient都有一个client和SurfaceFlinger通信了(也就是在SurfaceControl中能通过这个client,申请SurfaceFlinger创建一个layer,这种行为是每个SurfaceControl自己和SurfaceFlinger通信,而不是一起通过ComposerService一起喝SurfaceFlinger通信了)。








版权声明:本文为博主原创文章,未经博主允许不得转载。

Android framework层JNI的使用浅析

JNI技术对于多java开发的朋友相信并不陌生,即(java native interface),本地调用接口,主要功能有以下两点: 1、java层调用C/C++层代码 2、C/C++层调用java层...

Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView

SurfaceView, GLSurfaceView, SurfaceTexture以及TextureView是Android当中名字比较绕,关系又比较密切的几个类。本文基于Android 5.0(L...

android6.0 Activity(四) Surface创建

原文:http://blog.csdn.net/luoshengyang/article/details/8303098,原文代码比较老了,但是核心不变。在原文基础上修改了一些代码,以及加入自己少量的...

android之 JNI端获取并操作Surface

前一段时间研究android, 在jni端操作surface遇到麻烦,主要是C++基础太差,Surface.cpp读了n遍,也仿照网上查到的资料,试图从Java端传递Surface,然后jni端进行操...
  • dxpqxb
  • dxpqxb
  • 2012年10月17日 10:45
  • 1986

Android用surface直接显示yuv数据(三)

本文用Java创建UI并联合JNI层操作surface来直接显示yuv数据(yv12),开发环境为Android 4.4,全志A23平台。 package com.example.myyuvviewe...
  • tung214
  • tung214
  • 2014年07月14日 15:31
  • 11959

详解Android Surface系统

一 目的 本篇文章的目的就是为了讲清楚Android中的Surface系统,大家耳熟能详的SurfaceFlinger到底是个什么东西,它的工作流程又是怎样的。当然,鉴于SurfaceFling...

Android中SurfaceView的使用详解及如何在jni(hal层)直接显示

通过之前介绍的如何自定义View, 我们知道使用它可以做一些简单的动画效果。它通过不断循环的执行View.onDraw方法,每次执行都对内部显示的图形做一些调整,我们假设 onDraw方法每秒执行...
  • Nio96
  • Nio96
  • 2014年08月06日 15:21
  • 1205

Android6.0 显示系统(一) Surface创建

之前在分析Activity的时候,我们分析过Surface创建。这个系列的博客是讲述显示系统,这里再系统的分析下Surface创建过程。 之前我们分析在Activity在调用attach方法时,建立V...

android中的surface

在android中,对view及其子类,都是画在surface上的。每个window对应一个surface,各surface对象通过surfaceflinger合成到framebuffer,每个sur...
  • hgl868
  • hgl868
  • 2012年04月11日 14:20
  • 2981

[深入理解Android卷一全文-第八章]深入理解Surface系统

由于《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容。第8章  深入理解Surf...
  • Innost
  • Innost
  • 2015年08月02日 16:34
  • 11032
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android6.0 SurfaceControl分析(一)SurfaceControl创建&使用 Surface创建&使用
举报原因:
原因补充:

(最多只允许输入30个字)