Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 163766cb authored by Jason Sams's avatar Jason Sams
Browse files

Beging IO stream out from allocation to surface texture.

Change-Id: I4d6b7f7740a896d39b811d6fe7532bb00db62373
parent ea555e27
Loading
Loading
Loading
Loading
+79 −16
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ public class Allocation extends BaseObj {
    public static final int USAGE_SCRIPT = 0x0001;

    /**
     * GRAPHICS_TEXTURE The allcation will be used as a texture
     * GRAPHICS_TEXTURE The allocation will be used as a texture
     * source by one or more graphics programs.
     *
     */
@@ -124,34 +124,34 @@ public class Allocation extends BaseObj {
    public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;

    /**
     * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
     * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
     * target for offscreen rendering
     *
     */
    public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;

    /**
     * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allocation will be
     * used with a SurfaceTexture object.  This usage will cause the
     * allocation to be created read only.
     * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE The allocation
     * will be used as a SurfaceTexture graphics consumer. This
     * usage may only be used with USAGE_GRAPHICS_TEXTURE.
     *
     * @hide
     */
    public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020;

    /**
     * USAGE_IO_INPUT The allocation will be
     * used with a SurfaceTexture object.  This usage will cause the
     * allocation to be created read only.
     * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
     * consumer.  This usage will cause the allocation to be created
     * read only.
     *
     * @hide
     */
    public static final int USAGE_IO_INPUT = 0x0040;

    /**
     * USAGE_IO_OUTPUT The allocation will be
     * used with a SurfaceTexture object.  This usage will cause the
     * allocation to be created write only.
     * USAGE_IO_OUTPUT The allocation will be used as a
     * SurfaceTexture producer.  The dimensions and format of the
     * SurfaceTexture will be forced to those of the allocation.
     *
     * @hide
     */
@@ -323,6 +323,37 @@ public class Allocation extends BaseObj {
        mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
    }

    /**
     * Send a buffer to the output stream.  The contents of the
     * Allocation will be undefined after this operation.
     *
     * @hide
     *
     */
    public void ioSendOutput() {
        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
            throw new RSIllegalArgumentException(
                "Can only send buffer if IO_OUTPUT usage specified.");
        }
        mRS.validate();
        mRS.nAllocationIoSend(getID());
    }

    /**
     * Receive the latest input into the Allocation.
     *
     * @hide
     *
     */
    public void ioGetInput() {
        if ((mUsage & USAGE_IO_INPUT) == 0) {
            throw new RSIllegalArgumentException(
                "Can only send buffer if IO_OUTPUT usage specified.");
        }
        mRS.validate();
        mRS.nAllocationIoReceive(getID());
    }

    public void copyFrom(BaseObj[] d) {
        mRS.validate();
        validateIsObject();
@@ -887,17 +918,37 @@ public class Allocation extends BaseObj {
        updateCacheInfo(mType);
    }

    /*
    /**
     * Resize a 2D allocation.  The contents of the allocation are
     * preserved.  If new elements are allocated objects are created
     * with null contents and the new region is otherwise undefined.
     *
     * If the new region is smaller the references of any objects
     * outside the new region will be released.
     *
     * A new type will be created with the new dimension.
     *
     * @hide
     * @param dimX The new size of the allocation.
     * @param dimY The new size of the allocation.
     */
    public void resize(int dimX, int dimY) {
        if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
            throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
        if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
            throw new RSInvalidStateException(
                "Resize only support for 2D allocations at this time.");
        }
        if (mType.getY() == 0) {
            throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
            throw new RSInvalidStateException(
                "Resize only support for 2D allocations at this time.");
        }
        mRS.nAllocationResize2D(getID(), dimX, dimY);
        mRS.finish();  // Necessary because resize is fifoed and update is async.

        int typeID = mRS.nAllocationGetType(getID());
        mType = new Type(typeID, mRS);
        mType.updateFromNative();
        updateCacheInfo(mType);
    }
    */



@@ -1090,6 +1141,18 @@ public class Allocation extends BaseObj {

    }

    /**
     * @hide
     */
    public void setSurfaceTexture(SurfaceTexture sur) {
        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
            throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
        }

        mRS.validate();
        mRS.nAllocationSetSurfaceTexture(getID(), sur);
    }


    /**
     * Creates a non-mipmapped renderscript allocation to use as a
+16 −0
Original line number Diff line number Diff line
@@ -274,6 +274,22 @@ public class RenderScript {
        validate();
        return rsnAllocationGetSurfaceTextureID(mContext, alloc);
    }
    native void rsnAllocationSetSurfaceTexture(int con, int alloc, SurfaceTexture sur);
    synchronized void nAllocationSetSurfaceTexture(int alloc, SurfaceTexture sur) {
        validate();
        rsnAllocationSetSurfaceTexture(mContext, alloc, sur);
    }
    native void rsnAllocationIoSend(int con, int alloc);
    synchronized void nAllocationIoSend(int alloc) {
        validate();
        rsnAllocationIoSend(mContext, alloc);
    }
    native void rsnAllocationIoReceive(int con, int alloc);
    synchronized void nAllocationIoReceive(int alloc) {
        validate();
        rsnAllocationIoReceive(mContext, alloc);
    }


    native void rsnAllocationGenerateMipmaps(int con, int alloc);
    synchronized void nAllocationGenerateMipmaps(int alloc) {
+34 −0
Original line number Diff line number Diff line
@@ -450,6 +450,37 @@ nAllocationGetSurfaceTextureID(JNIEnv *_env, jobject _this, RsContext con, jint
    return rsAllocationGetSurfaceTextureID(con, (RsAllocation)a);
}

static void
nAllocationSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con,
                             RsAllocation alloc, jobject sur)
{
    LOG_API("nAllocationSetSurfaceTexture, con(%p), alloc(%p), surface(%p)",
            con, alloc, (Surface *)sur);

    sp<ANativeWindow> window;
    if (sur != 0) {
        sp<SurfaceTexture> st = SurfaceTexture_getSurfaceTexture(_env, sur);
        window = new SurfaceTextureClient(st);
    }

    rsAllocationSetSurface(con, alloc, window.get());
}

static void
nAllocationIoSend(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
{
    LOG_API("nAllocationIoSend, con(%p), alloc(%p)", con, alloc);
    rsAllocationIoSend(con, alloc);
}

static void
nAllocationIoReceive(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
{
    LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", con, alloc);
    rsAllocationIoReceive(con, alloc);
}


static void
nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
{
@@ -1277,6 +1308,9 @@ static JNINativeMethod methods[] = {

{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
{"rsnAllocationGetSurfaceTextureID", "(II)I",                                 (void*)nAllocationGetSurfaceTextureID },
{"rsnAllocationSetSurfaceTexture",   "(IILandroid/graphics/SurfaceTexture;)V", (void*)nAllocationSetSurfaceTexture },
{"rsnAllocationIoSend",              "(II)V",                                 (void*)nAllocationIoSend },
{"rsnAllocationIoReceive",           "(II)V",                                 (void*)nAllocationIoReceive },
{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
+95 −2
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@

#include "rsAllocation.h"

#include "system/window.h"
#include "hardware/gralloc.h"
#include "ui/Rect.h"
#include "ui/GraphicBufferMapper.h"

#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES/glext.h>
@@ -220,7 +225,8 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
    }

    void * ptr = alloc->mHal.state.usrPtr;
    if (!ptr) {
    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
    } else {
        ptr = malloc(alloc->mHal.state.type->getSizeBytes());
        if (!ptr) {
            free(drv);
@@ -248,7 +254,7 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
    alloc->mHal.drvState.mallocPtr = ptr;
    drv->mallocPtr = (uint8_t *)ptr;
    alloc->mHal.drv = drv;
    if (forceZero) {
    if (forceZero && ptr) {
        memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
    }

@@ -386,6 +392,93 @@ int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *al
    return drv->textureID;
}

static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer);
    if (r) {
        rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
        return false;
    }

    // This lock is implicitly released by the queue buffer in IoSend
    r = nw->lockBuffer(nw, drv->wndBuffer);
    if (r) {
        rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer.");
        return false;
    }

    // Must lock the whole surface
    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
    Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);

    void *dst = NULL;
    mapper.lock(drv->wndBuffer->handle,
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
            bounds, &dst);
    alloc->mHal.drvState.mallocPtr = dst;
    return true;
}

void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    //ALOGE("rsdAllocationSetSurfaceTexture %p  %p", alloc, nw);

    // Cleanup old surface if there is one.
    if (alloc->mHal.state.wndSurface) {
        ANativeWindow *old = alloc->mHal.state.wndSurface;
        GraphicBufferMapper &mapper = GraphicBufferMapper::get();
        mapper.unlock(drv->wndBuffer->handle);
        old->queueBuffer(old, drv->wndBuffer);
    }

    if (nw != NULL) {
        int32_t r;
        r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY |
                                        GRALLOC_USAGE_SW_WRITE_OFTEN);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
            return;
        }

        r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX,
                                                 alloc->mHal.state.dimensionY);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
            return;
        }

        r = native_window_set_buffer_count(nw, 3);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
            return;
        }

        IoGetBuffer(rsc, alloc, nw);
    }
}

void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    ANativeWindow *nw = alloc->mHal.state.wndSurface;

    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
    mapper.unlock(drv->wndBuffer->handle);
    int32_t r = nw->queueBuffer(nw, drv->wndBuffer);
    if (r) {
        rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
        return;
    }

    IoGetBuffer(rsc, alloc, nw);
}

void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
    ALOGE("not implemented");
}


void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
                         uint32_t xoff, uint32_t lod, uint32_t count,
                         const void *data, uint32_t sizeBytes) {
+8 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <GLES2/gl2.h>

class RsdFrameBufferObj;
struct ANativeWindowBuffer;

struct DrvAllocation {
    // Is this a legal structure to be used as a texture source.
@@ -47,6 +48,7 @@ struct DrvAllocation {
    bool uploadDeferred;

    RsdFrameBufferObj * readBackFBO;
    ANativeWindowBuffer *wndBuffer;
};

GLenum rsdTypeToGLType(RsDataType t);
@@ -69,6 +71,12 @@ void rsdAllocationMarkDirty(const android::renderscript::Context *rsc,
                            const android::renderscript::Allocation *alloc);
int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc,
                                        const android::renderscript::Allocation *alloc);
void rsdAllocationSetSurfaceTexture(const android::renderscript::Context *rsc,
                                    android::renderscript::Allocation *alloc, ANativeWindow *nw);
void rsdAllocationIoSend(const android::renderscript::Context *rsc,
                         android::renderscript::Allocation *alloc);
void rsdAllocationIoReceive(const android::renderscript::Context *rsc,
                            android::renderscript::Allocation *alloc);

void rsdAllocationData1D(const android::renderscript::Context *rsc,
                         const android::renderscript::Allocation *alloc,
Loading