Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2|回复: 1
打印 上一主题 下一主题

android的eglSwapBuffers如何和SurfaceFlinger联系上的

[复制链接]

1198

主题

2060

帖子

7058

积分

超级版主

Rank: 8Rank: 8

积分
7058
跳转到指定楼层
楼主
发表于 2016-5-7 13:23:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
frameworks/native/opengl/libagl/egl.cpp:::
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
    if (!d->isValid())
        return setError(EGL_BAD_SURFACE, EGL_FALSE);
    if (d->dpy != dpy)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    // post the surface
    d->swapBuffers();

    // if it's bound to a context, update the buffer
    if (d->ctx != EGL_NO_CONTEXT) {
        d->bindDrawSurface((ogles_context_t*)d->ctx);
        // if this surface is also the read surface of the context
        // it is bound to, make sure to update the read buffer as well.
        // The EGL spec is a little unclear about this.
        egl_context_t* c = egl_context_t::context(d->ctx);
        if (c->read == draw) {
            d->bindReadSurface((ogles_context_t*)d->ctx);
        }
    }

    return EGL_TRUE;
}


回复

使用道具 举报

1198

主题

2060

帖子

7058

积分

超级版主

Rank: 8Rank: 8

积分
7058
沙发
 楼主| 发表于 2016-5-7 13:25:16 | 只看该作者
EGLBoolean egl_window_surface_v2_t::swapBuffers()
{
    if (!buffer) {
        return setError(EGL_BAD_ACCESS, EGL_FALSE);
    }
   
    /*
     * Handle eglSetSwapRectangleANDROID()
     * We copyback from the front buffer
     */
    if (!dirtyRegion.isEmpty()) {
        dirtyRegion.andSelf(Rect(buffer->width, buffer->height));
        if (previousBuffer) {
            // This was const Region copyBack, but that causes an
            // internal compile error on simulator builds
            /*const*/ Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion));
            if (!copyBack.isEmpty()) {
                void* prevBits;
                if (lock(previousBuffer,
                        GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) {
                    // copy from previousBuffer to buffer
                    copyBlt(buffer, bits, previousBuffer, prevBits, copyBack);
                    unlock(previousBuffer);
                }
            }
        }
        oldDirtyRegion = dirtyRegion;
    }

    if (previousBuffer) {
        previousBuffer->common.decRef(&previousBuffer->common);
        previousBuffer = 0;
    }
   
    unlock(buffer);
    previousBuffer = buffer;
    nativeWindow->queueBuffer(nativeWindow, buffer, -1);
    buffer = 0;

    // dequeue a new buffer
    int fenceFd = -1;
    if (nativeWindow->dequeueBuffer(nativeWindow, &buffer, &fenceFd) == NO_ERROR) {
        sp<Fence> fence(new Fence(fenceFd));
        if (fence->wait(Fence::TIMEOUT_NEVER)) {
            nativeWindow->cancelBuffer(nativeWindow, buffer, fenceFd);
            return setError(EGL_BAD_ALLOC, EGL_FALSE);
        }

        // reallocate the depth-buffer if needed
        if ((width != buffer->width) || (height != buffer->height)) {
            // TODO: we probably should reset the swap rect here
            // if the window size has changed
            width = buffer->width;
            height = buffer->height;
            if (depth.data) {
                free(depth.data);
                depth.width   = width;
                depth.height  = height;
                depth.stride  = buffer->stride;
                depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
                if (depth.data == 0) {
                    setError(EGL_BAD_ALLOC, EGL_FALSE);
                    return EGL_FALSE;
                }
            }
        }

        // keep a reference on the buffer
        buffer->common.incRef(&buffer->common);

        // finally pin the buffer down
        if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN |
                GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
            ALOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
                    buffer, buffer->width, buffer->height);
            return setError(EGL_BAD_ACCESS, EGL_FALSE);
            // FIXME: we should make sure we're not accessing the buffer anymore
        }
    } else {
        return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
    }

    return EGL_TRUE;
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Comsenz Inc.

GMT+8, 2025-12-15 01:42 , Processed in 0.013161 second(s), 7 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表