diff options
Diffstat (limited to 'libs/rs')
-rw-r--r-- | libs/rs/Android.mk | 1 | ||||
-rw-r--r-- | libs/rs/driver/rsdAllocation.cpp | 397 | ||||
-rw-r--r-- | libs/rs/driver/rsdAllocation.h | 88 | ||||
-rw-r--r-- | libs/rs/driver/rsdCore.cpp | 14 | ||||
-rw-r--r-- | libs/rs/driver/rsdFrameBuffer.cpp | 27 | ||||
-rw-r--r-- | libs/rs/driver/rsdMeshObj.cpp | 31 | ||||
-rw-r--r-- | libs/rs/driver/rsdProgram.cpp | 13 | ||||
-rw-r--r-- | libs/rs/driver/rsdShader.cpp | 18 | ||||
-rw-r--r-- | libs/rs/rsAllocation.cpp | 438 | ||||
-rw-r--r-- | libs/rs/rsAllocation.h | 75 | ||||
-rw-r--r-- | libs/rs/rsContext.h | 7 | ||||
-rw-r--r-- | libs/rs/rsFBOCache.cpp | 18 | ||||
-rw-r--r-- | libs/rs/rsFont.cpp | 17 | ||||
-rw-r--r-- | libs/rs/rsMesh.cpp | 13 | ||||
-rw-r--r-- | libs/rs/rsProgramFragment.cpp | 4 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 3 | ||||
-rw-r--r-- | libs/rs/rsRuntime.h | 6 | ||||
-rw-r--r-- | libs/rs/rs_hal.h | 29 |
18 files changed, 679 insertions, 520 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 29c1447..9c9fae3 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -115,6 +115,7 @@ LOCAL_SRC_FILES:= \ rsStream.cpp \ rsThreadIO.cpp \ rsType.cpp \ + driver/rsdAllocation.cpp \ driver/rsdBcc.cpp \ driver/rsdCore.cpp \ driver/rsdFrameBuffer.cpp \ diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp new file mode 100644 index 0000000..f58fe1a --- /dev/null +++ b/libs/rs/driver/rsdAllocation.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "rsdCore.h" +#include "rsdBcc.h" +#include "rsdRuntime.h" +#include "rsdAllocation.h" + +#include "rsAllocation.h" + +#include <GLES/gl.h> +#include <GLES2/gl2.h> +#include <GLES/glext.h> + +using namespace android; +using namespace android::renderscript; + + + +const static GLenum gFaceOrder[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z +}; + + +static void Update2DTexture(const Allocation *alloc, const void *ptr, uint32_t xoff, uint32_t yoff, + uint32_t lod, RsAllocationCubemapFace face, + uint32_t w, uint32_t h) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + const GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType(); + const GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat(); + rsAssert(drv->textureID); + glBindTexture(drv->glTarget, drv->textureID); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + GLenum t = GL_TEXTURE_2D; + if (alloc->mHal.state.hasFaces) { + t = gFaceOrder[face]; + } + glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr); +} + + +static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType(); + GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat(); + + glBindTexture(drv->glTarget, drv->textureID); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + uint32_t faceCount = 1; + if (alloc->mHal.state.hasFaces) { + faceCount = 6; + } + + rsdGLCheckError(rsc, "Upload2DTexture 1 "); + for (uint32_t face = 0; face < faceCount; face ++) { + for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) { + const uint8_t *p = (const uint8_t *)drv->mallocPtr; + p += alloc->mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0); + + GLenum t = GL_TEXTURE_2D; + if (alloc->mHal.state.hasFaces) { + t = gFaceOrder[face]; + } + + if (isFirstUpload) { + glTexImage2D(t, lod, format, + alloc->mHal.state.type->getLODDimX(lod), + alloc->mHal.state.type->getLODDimY(lod), + 0, format, type, p); + } else { + glTexSubImage2D(t, lod, 0, 0, + alloc->mHal.state.type->getLODDimX(lod), + alloc->mHal.state.type->getLODDimY(lod), + format, type, p); + } + } + } + + if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) { + glGenerateMipmap(drv->glTarget); + } + rsdGLCheckError(rsc, "Upload2DTexture"); +} + +static void UploadToTexture(const Context *rsc, const Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + GLenum type = alloc->mHal.state.type->getElement()->getComponent().getGLType(); + GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat(); + + if (!type || !format) { + return; + } + + if (!alloc->getPtr()) { + return; + } + + bool isFirstUpload = false; + + if (!drv->textureID) { + glGenTextures(1, &drv->textureID); + isFirstUpload = true; + } + + Upload2DTexture(rsc, alloc, isFirstUpload); + + if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { + if (drv->mallocPtr) { + free(drv->mallocPtr); + drv->mallocPtr = NULL; + } + } + rsdGLCheckError(rsc, "UploadToTexture"); +} + +static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + GLenum format = alloc->mHal.state.type->getElement()->getComponent().getGLFormat(); + if (!format) { + return; + } + + if (!drv->renderTargetID) { + glGenRenderbuffers(1, &drv->renderTargetID); + + if (!drv->renderTargetID) { + // This should generally not happen + LOGE("allocateRenderTarget failed to gen mRenderTargetID"); + rsc->dumpDebug(); + return; + } + glBindRenderbuffer(GL_RENDERBUFFER, drv->renderTargetID); + glRenderbufferStorage(GL_RENDERBUFFER, format, + alloc->mHal.state.dimensionX, alloc->mHal.state.dimensionY); + } + rsdGLCheckError(rsc, "AllocateRenderTarget"); +} + +static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + rsAssert(!alloc->mHal.state.type->getDimY()); + rsAssert(!alloc->mHal.state.type->getDimZ()); + + //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX; + + if (!drv->bufferID) { + glGenBuffers(1, &drv->bufferID); + } + if (!drv->bufferID) { + LOGE("Upload to buffer object failed"); + drv->uploadDeferred = true; + return; + } + glBindBuffer(drv->glTarget, drv->bufferID); + glBufferData(drv->glTarget, alloc->mHal.state.type->getSizeBytes(), + drv->mallocPtr, GL_DYNAMIC_DRAW); + glBindBuffer(drv->glTarget, 0); + rsdGLCheckError(rsc, "UploadToBufferObject"); +} + +bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { + DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation)); + if (!drv) { + return false; + } + + void * ptr = malloc(alloc->mHal.state.type->getSizeBytes()); + if (!ptr) { + free(drv); + return false; + } + + drv->glTarget = GL_NONE; + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) { + if (alloc->mHal.state.hasFaces) { + drv->glTarget = GL_TEXTURE_CUBE_MAP; + } else { + drv->glTarget = GL_TEXTURE_2D; + } + } else { + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) { + drv->glTarget = GL_ARRAY_BUFFER; + } + } + + alloc->mHal.drvState.mallocPtr = ptr; + drv->mallocPtr = (uint8_t *)ptr; + alloc->mHal.drv = drv; + if (forceZero) { + memset(ptr, 0, alloc->mHal.state.type->getSizeBytes()); + } + + if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) { + drv->uploadDeferred = true; + } + return true; +} + +void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + if (drv->bufferID) { + // Causes a SW crash.... + //LOGV(" mBufferID %i", mBufferID); + //glDeleteBuffers(1, &mBufferID); + //mBufferID = 0; + } + if (drv->textureID) { + glDeleteTextures(1, &drv->textureID); + drv->textureID = 0; + } + if (drv->renderTargetID) { + glDeleteRenderbuffers(1, &drv->renderTargetID); + drv->renderTargetID = 0; + } + + if (drv->mallocPtr) { + free(drv->mallocPtr); + drv->mallocPtr = NULL; + } + free(drv); + alloc->mHal.drv = NULL; +} + +void rsdAllocationResize(const Context *rsc, const Allocation *alloc, + const Type *newType, bool zeroNew) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + drv->mallocPtr = (uint8_t *)realloc(drv->mallocPtr, newType->getSizeBytes()); + + // fixme + ((Allocation *)alloc)->mHal.drvState.mallocPtr = drv->mallocPtr; + + const uint32_t oldDimX = alloc->mHal.state.dimensionX; + const uint32_t dimX = newType->getDimX(); + + if (dimX > oldDimX) { + const Element *e = alloc->mHal.state.type->getElement(); + uint32_t stride = e->getSizeBytes(); + memset(((uint8_t *)drv->mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX)); + } +} + + + +void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, + RsAllocationUsageType src) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + if (!drv->uploadDeferred) { + return; + } + + rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT); + + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) { + UploadToTexture(rsc, alloc); + } else { + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { + AllocateRenderTarget(rsc, alloc); + } + } + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) { + UploadToBufferObject(rsc, alloc); + } + + drv->uploadDeferred = false; +} + +void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + drv->uploadDeferred = true; +} + +void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, + uint32_t xoff, uint32_t lod, uint32_t count, + const void *data, uint32_t sizeBytes) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes(); + uint8_t * ptr = drv->mallocPtr; + ptr += eSize * xoff; + uint32_t size = count * eSize; + + if (alloc->mHal.state.hasReferences) { + alloc->incRefs(data, count); + alloc->decRefs(ptr, count); + } + + memcpy(ptr, data, size); + drv->uploadDeferred = true; +} + +void rsdAllocationData2D(const Context *rsc, const Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, + uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + uint32_t eSize = alloc->mHal.state.elementSizeBytes; + uint32_t lineSize = eSize * w; + uint32_t destW = alloc->mHal.state.dimensionX; + + if (drv->mallocPtr) { + const uint8_t *src = static_cast<const uint8_t *>(data); + uint8_t *dst = drv->mallocPtr; + dst += alloc->mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff); + + for (uint32_t line=yoff; line < (yoff+h); line++) { + if (alloc->mHal.state.hasReferences) { + alloc->incRefs(src, w); + alloc->decRefs(dst, w); + } + memcpy(dst, src, lineSize); + src += lineSize; + dst += destW * eSize; + } + drv->uploadDeferred = true; + } else { + Update2DTexture(alloc, data, xoff, yoff, lod, face, w, h); + } +} + +void rsdAllocationData3D(const Context *rsc, const Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t zoff, + uint32_t lod, RsAllocationCubemapFace face, + uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) { + +} + +void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc, + uint32_t x, + const void *data, uint32_t cIdx, uint32_t sizeBytes) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + uint32_t eSize = alloc->mHal.state.elementSizeBytes; + uint8_t * ptr = drv->mallocPtr; + ptr += eSize * x; + + const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); + ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); + + if (alloc->mHal.state.hasReferences) { + e->incRefs(data); + e->decRefs(ptr); + } + + memcpy(ptr, data, sizeBytes); + drv->uploadDeferred = true; +} + +void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc, + uint32_t x, uint32_t y, + const void *data, uint32_t cIdx, uint32_t sizeBytes) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + uint32_t eSize = alloc->mHal.state.elementSizeBytes; + uint8_t * ptr = drv->mallocPtr; + ptr += eSize * (x + y * alloc->mHal.state.dimensionX); + + const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx); + ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); + + if (alloc->mHal.state.hasReferences) { + e->incRefs(data); + e->decRefs(ptr); + } + + memcpy(ptr, data, sizeBytes); + drv->uploadDeferred = true; +} + + diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h new file mode 100644 index 0000000..45a538b --- /dev/null +++ b/libs/rs/driver/rsdAllocation.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RSD_ALLOCATION_H +#define RSD_ALLOCATION_H + +#include <rs_hal.h> +#include <rsRuntime.h> + +#include <GLES/gl.h> +#include <GLES2/gl2.h> + +struct DrvAllocation { + // Is this a legal structure to be used as a texture source. + // Initially this will require 1D or 2D and color data + uint32_t textureID; + + // Is this a legal structure to be used as a vertex source. + // Initially this will require 1D and x(yzw). Additional per element data + // is allowed. + uint32_t bufferID; + + // Is this a legal structure to be used as an FBO render target + uint32_t renderTargetID; + + uint8_t * mallocPtr; + + GLenum glTarget; + + bool uploadDeferred; +}; + +bool rsdAllocationInit(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc, + bool forceZero); +void rsdAllocationDestroy(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); + +void rsdAllocationResize(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + const android::renderscript::Type *newType, bool zeroNew); +void rsdAllocationSyncAll(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + RsAllocationUsageType src); +void rsdAllocationMarkDirty(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc); + +void rsdAllocationData1D(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + uint32_t xoff, uint32_t lod, uint32_t count, + const void *data, uint32_t sizeBytes); +void rsdAllocationData2D(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, + uint32_t w, uint32_t h, + const void *data, uint32_t sizeBytes); +void rsdAllocationData3D(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t zoff, + uint32_t lod, RsAllocationCubemapFace face, + uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes); + +void rsdAllocationElementData1D(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + uint32_t x, + const void *data, uint32_t elementOff, uint32_t sizeBytes); +void rsdAllocationElementData2D(const android::renderscript::Context *rsc, + const android::renderscript::Allocation *alloc, + uint32_t x, uint32_t y, + const void *data, uint32_t elementOff, uint32_t sizeBytes); + + + + +#endif diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp index 7ef9c30..94d55a6 100644 --- a/libs/rs/driver/rsdCore.cpp +++ b/libs/rs/driver/rsdCore.cpp @@ -15,6 +15,7 @@ */ #include "rsdCore.h" +#include "rsdAllocation.h" #include "rsdBcc.h" #include "rsdGL.h" #include "rsdProgramStore.h" @@ -63,6 +64,19 @@ static RsdHalFunctions FunctionTable = { rsdScriptDestroy }, + { + rsdAllocationInit, + rsdAllocationDestroy, + rsdAllocationResize, + rsdAllocationSyncAll, + rsdAllocationMarkDirty, + rsdAllocationData1D, + rsdAllocationData2D, + rsdAllocationData3D, + rsdAllocationElementData1D, + rsdAllocationElementData2D + }, + { rsdProgramStoreInit, diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp index 6a7dac4..ce72b5d 100644 --- a/libs/rs/driver/rsdFrameBuffer.cpp +++ b/libs/rs/driver/rsdFrameBuffer.cpp @@ -17,6 +17,7 @@ #include "rsdCore.h" #include "rsdFrameBuffer.h" +#include "rsdAllocation.h" #include "rsContext.h" #include "rsFBOCache.h" @@ -59,21 +60,19 @@ void checkError(const Context *rsc) { void setDepthAttachment(const Context *rsc, const FBOCache *fb) { if (fb->mHal.state.depthTarget.get() != NULL) { - if (fb->mHal.state.depthTarget->getIsTexture()) { - uint32_t texID = fb->mHal.state.depthTarget->getTextureID(); + DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; + + if (drv->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, texID, 0); + GL_TEXTURE_2D, drv->textureID, 0); } else { - uint32_t texID = fb->mHal.state.depthTarget->getRenderTargetID(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, texID); + GL_RENDERBUFFER, drv->renderTargetID); } } else { // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, 0, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } } @@ -82,14 +81,14 @@ void setColorAttachment(const Context *rsc, const FBOCache *fb) { for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { uint32_t texID = 0; if (fb->mHal.state.colorTargets[i].get() != NULL) { - if (fb->mHal.state.colorTargets[i]->getIsTexture()) { - uint32_t texID = fb->mHal.state.colorTargets[i]->getTextureID(); + DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; + + if (drv->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, texID, 0); + GL_TEXTURE_2D, drv->textureID, 0); } else { - uint32_t texID = fb->mHal.state.depthTarget->getRenderTargetID(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, texID); + GL_RENDERBUFFER, drv->renderTargetID); } } else { // Reset last attachment diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp index 2c07784..260595c 100644 --- a/libs/rs/driver/rsdMeshObj.cpp +++ b/libs/rs/driver/rsdMeshObj.cpp @@ -22,6 +22,7 @@ #include <rsContext.h> #include <rsMesh.h> +#include "rsdAllocation.h" #include "rsdMeshObj.h" #include "rsdGL.h" @@ -135,28 +136,42 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui return; } - rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange 1"); + for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { + const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct].get(); + rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + } + // update attributes with either buffer information or data ptr based on their current state for (uint32_t ct=0; ct < mAttribCount; ct++) { uint32_t allocIndex = mAttribAllocationIndex[ct]; Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex].get(); - if (alloc->getIsBufferObject() && alloc->getBufferObjectID()) { - mAttribs[ct].buffer = alloc->getBufferObjectID(); + DrvAllocation *drvAlloc = (DrvAllocation *)alloc->mHal.drv; + + if (drvAlloc->bufferID) { + mAttribs[ct].buffer = drvAlloc->bufferID; mAttribs[ct].ptr = NULL; } else { mAttribs[ct].buffer = 0; - mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr(); + mAttribs[ct].ptr = (const uint8_t*)drvAlloc->mallocPtr; } } RsdVertexArray va(mAttribs, mAttribCount); va.setup(rsc); - rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange 2"); Mesh::Primitive_t *prim = mRSMesh->mHal.state.primitives[primIndex]; - if (prim->mIndexBuffer.get()) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID()); - glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2)); + const Allocation *idxAlloc = prim->mIndexBuffer.get(); + if (idxAlloc) { + DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; + rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + + if (drvAlloc->bufferID) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); + glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2)); + } else { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, drvAlloc->mallocPtr); + } } else { glDrawArrays(mGLPrimitives[primIndex], start, len); } diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp index 502c5ee..39b3805 100644 --- a/libs/rs/driver/rsdProgram.cpp +++ b/libs/rs/driver/rsdProgram.cpp @@ -16,6 +16,7 @@ #include "rsdCore.h" +#include "rsdAllocation.h" #include "rsdProgramVertex.h" #include "rsdShader.h" #include "rsdShaderCache.h" @@ -40,9 +41,20 @@ bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv, return drv->createShader(); } +static void SyncProgramConstants(const Context *rsc, const Program *p) { + for (uint32_t ct=0; ct < p->mHal.state.texturesCount; ct++) { + const Allocation *a = p->mHal.state.textures[ct].get(); + DrvAllocation *drvAlloc = (DrvAllocation *)a->mHal.drv; + if (drvAlloc->uploadDeferred) { + rsdAllocationSyncAll(rsc, a, RS_ALLOCATION_USAGE_SCRIPT); + } + } +} + void rsdProgramVertexSetActive(const Context *rsc, const ProgramVertex *pv) { RsdHal *dc = (RsdHal *)rsc->mHal.drv; + SyncProgramConstants(rsc, pv); dc->gl.shaderCache->setActiveVertex((RsdShader*)pv->mHal.drv); } @@ -73,6 +85,7 @@ bool rsdProgramFragmentInit(const Context *rsc, const ProgramFragment *pf, void rsdProgramFragmentSetActive(const Context *rsc, const ProgramFragment *pf) { RsdHal *dc = (RsdHal *)rsc->mHal.drv; + SyncProgramConstants(rsc, pf); dc->gl.shaderCache->setActiveFragment((RsdShader*)pf->mHal.drv); } diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp index 371266b..15cc417 100644 --- a/libs/rs/driver/rsdShader.cpp +++ b/libs/rs/driver/rsdShader.cpp @@ -22,6 +22,7 @@ #include <rsProgram.h> #include "rsdCore.h" +#include "rsdAllocation.h" #include "rsdShader.h" #include "rsdShaderCache.h" @@ -338,7 +339,8 @@ void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocat }; // This tells us the correct texture type - GLenum target = (GLenum)tex->getGLTarget(); + DrvAllocation *drvTex = (DrvAllocation *)tex->mHal.drv; + const GLenum target = drvTex->glTarget; if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) { if (tex->getHasGraphicsMipmaps() && @@ -404,20 +406,20 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) { continue; } - GLenum target = (GLenum)mRSProgram->mHal.state.textures[ct]->getGLTarget(); - if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) { + DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv; + if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) { LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct); rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader"); } - glBindTexture(target, mRSProgram->mHal.state.textures[ct]->getTextureID()); + glBindTexture(drvTex->glTarget, drvTex->textureID); rsdGLCheckError(rsc, "ProgramFragment::setup tex bind"); if (mRSProgram->mHal.state.samplers[ct].get()) { setupSampler(rsc, mRSProgram->mHal.state.samplers[ct].get(), mRSProgram->mHal.state.textures[ct].get()); } else { - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(drvTex->glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); rsdGLCheckError(rsc, "ProgramFragment::setup tex env"); } diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 5b84ca6..05412c7 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -15,11 +15,8 @@ */ #include "rsContext.h" -#ifndef ANDROID_RS_SERIALIZE -#include <GLES/gl.h> -#include <GLES2/gl2.h> -#include <GLES/glext.h> -#endif //ANDROID_RS_SERIALIZE +#include "rs_hal.h" + using namespace android; using namespace android::renderscript; @@ -27,43 +24,26 @@ using namespace android::renderscript; Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages, RsAllocationMipmapControl mc) : ObjectBase(rsc) { - init(rsc, type); + memset(&mHal, 0, sizeof(mHal)); + mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; mHal.state.usageFlags = usages; mHal.state.mipmapControl = mc; - allocScriptMemory(); - if (mHal.state.type->getElement()->getHasReferences()) { - memset(mHal.state.mallocPtr, 0, mHal.state.type->getSizeBytes()); - } - if (!mHal.state.mallocPtr) { - LOGE("Allocation::Allocation, alloc failure"); - } + mHal.state.type.set(type); + updateCache(); } +Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages, + RsAllocationMipmapControl mc) { + Allocation *a = new Allocation(rsc, type, usages, mc); -void Allocation::init(Context *rsc, const Type *type) { - memset(&mHal, 0, sizeof(mHal)); - mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE; - - mCpuWrite = false; - mCpuRead = false; - mGpuWrite = false; - mGpuRead = false; - - mReadWriteRatio = 0; - mUpdateSize = 0; - - mTextureID = 0; - mBufferID = 0; - mRenderTargetID = 0; - mUploadDeferred = false; - - mUserBitmapCallback = NULL; - mUserBitmapCallbackData = NULL; - - mHal.state.type.set(type); - updateCache(); + if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) { + rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure"); + delete a; + return NULL; + } + return a; } void Allocation::updateCache() { @@ -78,304 +58,36 @@ void Allocation::updateCache() { } Allocation::~Allocation() { - if (mUserBitmapCallback != NULL) { - mUserBitmapCallback(mUserBitmapCallbackData); - mHal.state.mallocPtr = NULL; - } - freeScriptMemory(); -#ifndef ANDROID_RS_SERIALIZE - if (mBufferID) { - // Causes a SW crash.... - //LOGV(" mBufferID %i", mBufferID); - //glDeleteBuffers(1, &mBufferID); - //mBufferID = 0; - } - if (mTextureID) { - glDeleteTextures(1, &mTextureID); - mTextureID = 0; - } - if (mRenderTargetID) { - glDeleteRenderbuffers(1, &mRenderTargetID); - mRenderTargetID = 0; - } -#endif //ANDROID_RS_SERIALIZE -} - -void Allocation::setCpuWritable(bool) { -} - -void Allocation::setGpuWritable(bool) { -} - -void Allocation::setCpuReadable(bool) { -} - -void Allocation::setGpuReadable(bool) { -} - -bool Allocation::fixAllocation() { - return false; + mRSC->mHal.funcs.allocation.destroy(mRSC, this); } -void Allocation::deferredUploadToTexture(const Context *rsc) { - mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; - mUploadDeferred = true; -} - -void Allocation::deferredAllocateRenderTarget(const Context *rsc) { - mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET; - mUploadDeferred = true; -} - -uint32_t Allocation::getGLTarget() const { -#ifndef ANDROID_RS_SERIALIZE - if (getIsTexture()) { - if (mHal.state.type->getDimFaces()) { - return GL_TEXTURE_CUBE_MAP; - } else { - return GL_TEXTURE_2D; - } - } - if (getIsBufferObject()) { - return GL_ARRAY_BUFFER; - } -#endif //ANDROID_RS_SERIALIZE - return 0; -} - -void Allocation::allocScriptMemory() { - rsAssert(!mHal.state.mallocPtr); - mHal.state.mallocPtr = malloc(mHal.state.type->getSizeBytes()); -} - -void Allocation::freeScriptMemory() { - if (mHal.state.mallocPtr) { - free(mHal.state.mallocPtr); - mHal.state.mallocPtr = NULL; - } -} - - void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { - rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT); - - if (getIsTexture()) { - uploadToTexture(rsc); - } - if (getIsBufferObject()) { - uploadToBufferObject(rsc); - } - if (getIsRenderTarget() && !getIsTexture()) { - allocateRenderTarget(rsc); - } - - mUploadDeferred = false; -} - -void Allocation::uploadToTexture(const Context *rsc) { -#ifndef ANDROID_RS_SERIALIZE - mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; - GLenum type = mHal.state.type->getElement()->getComponent().getGLType(); - GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat(); - - if (!type || !format) { - return; - } - - if (!mHal.state.mallocPtr) { - return; - } - - bool isFirstUpload = false; - - if (!mTextureID) { - glGenTextures(1, &mTextureID); - - if (!mTextureID) { - // This should not happen, however, its likely the cause of the - // white sqare bug. - // Force a crash to 1: restart the app, 2: make sure we get a bugreport. - LOGE("Upload to texture failed to gen mTextureID"); - rsc->dumpDebug(); - mUploadDeferred = true; - return; - } - isFirstUpload = true; - } - - upload2DTexture(isFirstUpload); - - if (!(mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { - freeScriptMemory(); - } - - //rsc->checkError("Allocation::uploadToTexture"); -#endif //ANDROID_RS_SERIALIZE -} - -void Allocation::allocateRenderTarget(const Context *rsc) { -#ifndef ANDROID_RS_SERIALIZE - mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET; - - GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat(); - if (!format) { - return; - } - - if (!mRenderTargetID) { - glGenRenderbuffers(1, &mRenderTargetID); - - if (!mRenderTargetID) { - // This should generally not happen - LOGE("allocateRenderTarget failed to gen mRenderTargetID"); - rsc->dumpDebug(); - return; - } - glBindRenderbuffer(GL_RENDERBUFFER, mRenderTargetID); - glRenderbufferStorage(GL_RENDERBUFFER, format, - mHal.state.type->getDimX(), - mHal.state.type->getDimY()); - } -#endif //ANDROID_RS_SERIALIZE -} - -#ifndef ANDROID_RS_SERIALIZE -const static GLenum gFaceOrder[] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -}; -#endif //ANDROID_RS_SERIALIZE - -void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff, - uint32_t lod, RsAllocationCubemapFace face, - uint32_t w, uint32_t h) { -#ifndef ANDROID_RS_SERIALIZE - GLenum type = mHal.state.type->getElement()->getComponent().getGLType(); - GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat(); - GLenum target = (GLenum)getGLTarget(); - rsAssert(mTextureID); - glBindTexture(target, mTextureID); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLenum t = GL_TEXTURE_2D; - if (mHal.state.hasFaces) { - t = gFaceOrder[face]; - } - glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr); -#endif //ANDROID_RS_SERIALIZE -} - -void Allocation::upload2DTexture(bool isFirstUpload) { -#ifndef ANDROID_RS_SERIALIZE - GLenum type = mHal.state.type->getElement()->getComponent().getGLType(); - GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat(); - - GLenum target = (GLenum)getGLTarget(); - glBindTexture(target, mTextureID); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - uint32_t faceCount = 1; - if (mHal.state.hasFaces) { - faceCount = 6; - } - - for (uint32_t face = 0; face < faceCount; face ++) { - for (uint32_t lod = 0; lod < mHal.state.type->getLODCount(); lod++) { - const uint8_t *p = (const uint8_t *)mHal.state.mallocPtr; - p += mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0); - - GLenum t = GL_TEXTURE_2D; - if (mHal.state.hasFaces) { - t = gFaceOrder[face]; - } - - if (isFirstUpload) { - glTexImage2D(t, lod, format, - mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod), - 0, format, type, p); - } else { - glTexSubImage2D(t, lod, 0, 0, - mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod), - format, type, p); - } - } - } - - if (mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) { - glGenerateMipmap(target); - } -#endif //ANDROID_RS_SERIALIZE -} - -void Allocation::deferredUploadToBufferObject(const Context *rsc) { - mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX; - mUploadDeferred = true; -} - -void Allocation::uploadToBufferObject(const Context *rsc) { -#ifndef ANDROID_RS_SERIALIZE - rsAssert(!mHal.state.type->getDimY()); - rsAssert(!mHal.state.type->getDimZ()); - - mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX; - - if (!mBufferID) { - glGenBuffers(1, &mBufferID); - } - if (!mBufferID) { - LOGE("Upload to buffer object failed"); - mUploadDeferred = true; - return; - } - GLenum target = (GLenum)getGLTarget(); - glBindBuffer(target, mBufferID); - glBufferData(target, mHal.state.type->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW); - glBindBuffer(target, 0); - //rsc->checkError("Allocation::uploadToBufferObject"); -#endif //ANDROID_RS_SERIALIZE -} - -void Allocation::uploadCheck(Context *rsc) { - if (mUploadDeferred) { - syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } + rsc->mHal.funcs.allocation.syncAll(rsc, this, src); } void Allocation::read(void *data) { - memcpy(data, mHal.state.mallocPtr, mHal.state.type->getSizeBytes()); + memcpy(data, getPtr(), mHal.state.type->getSizeBytes()); } void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, const void *data, uint32_t sizeBytes) { - uint32_t eSize = mHal.state.type->getElementSizeBytes(); - uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr); - ptr += eSize * xoff; - uint32_t size = count * eSize; + const uint32_t eSize = mHal.state.type->getElementSizeBytes(); - if (size != sizeBytes) { - LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes); + if ((count * eSize) != sizeBytes) { + LOGE("Allocation::subData called with mismatched size expected %i, got %i", + (count * eSize), sizeBytes); mHal.state.type->dumpLOGV("type info"); return; } - if (mHal.state.hasReferences) { - incRefs(data, count); - decRefs(ptr, count); - } - - memcpy(ptr, data, size); - sendDirty(); - mUploadDeferred = true; + rsc->mHal.funcs.allocation.data1D(rsc, this, xoff, lod, count, data, sizeBytes); + sendDirty(rsc); } void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) { - uint32_t eSize = mHal.state.elementSizeBytes; - uint32_t lineSize = eSize * w; - uint32_t destW = mHal.state.dimensionX; + const uint32_t eSize = mHal.state.elementSizeBytes; + const uint32_t lineSize = eSize * w; //LOGE("data2d %p, %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes); @@ -385,26 +97,8 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, return; } - if (mHal.state.mallocPtr) { - const uint8_t *src = static_cast<const uint8_t *>(data); - uint8_t *dst = static_cast<uint8_t *>(mHal.state.mallocPtr); - dst += mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff); - - //LOGE(" %p %p %i ", dst, src, eSize); - for (uint32_t line=yoff; line < (yoff+h); line++) { - if (mHal.state.hasReferences) { - incRefs(src, w); - decRefs(dst, w); - } - memcpy(dst, src, lineSize); - src += lineSize; - dst += destW * eSize; - } - sendDirty(); - mUploadDeferred = true; - } else { - update2DTexture(data, xoff, yoff, lod, face, w, h); - } + rsc->mHal.funcs.allocation.data2D(rsc, this, xoff, yoff, lod, face, w, h, data, sizeBytes); + sendDirty(rsc); } void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, @@ -415,8 +109,6 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, void Allocation::elementData(Context *rsc, uint32_t x, const void *data, uint32_t cIdx, uint32_t sizeBytes) { uint32_t eSize = mHal.state.elementSizeBytes; - uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr); - ptr += eSize * x; if (cIdx >= mHal.state.type->getElement()->getFieldCount()) { LOGE("Error Allocation::subElementData component %i out of range.", cIdx); @@ -431,29 +123,19 @@ void Allocation::elementData(Context *rsc, uint32_t x, const void *data, } const Element * e = mHal.state.type->getElement()->getField(cIdx); - ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); - if (sizeBytes != e->getSizeBytes()) { LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes()); rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size."); return; } - if (e->getHasReferences()) { - e->incRefs(data); - e->decRefs(ptr); - } - - memcpy(ptr, data, sizeBytes); - sendDirty(); - mUploadDeferred = true; + rsc->mHal.funcs.allocation.elementData1D(rsc, this, x, data, cIdx, sizeBytes); + sendDirty(rsc); } void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, const void *data, uint32_t cIdx, uint32_t sizeBytes) { uint32_t eSize = mHal.state.elementSizeBytes; - uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr); - ptr += eSize * (x + y * mHal.state.dimensionX); if (x >= mHal.state.dimensionX) { LOGE("Error Allocation::subElementData X offset %i out of range.", x); @@ -474,7 +156,6 @@ void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, } const Element * e = mHal.state.type->getElement()->getField(cIdx); - ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx); if (sizeBytes != e->getSizeBytes()) { LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes()); @@ -482,14 +163,8 @@ void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y, return; } - if (e->getHasReferences()) { - e->incRefs(data); - e->decRefs(ptr); - } - - memcpy(ptr, data, sizeBytes); - sendDirty(); - mUploadDeferred = true; + rsc->mHal.funcs.allocation.elementData2D(rsc, this, x, y, data, cIdx, sizeBytes); + sendDirty(rsc); } void Allocation::addProgramToDirty(const Program *p) { @@ -519,11 +194,8 @@ void Allocation::dumpLOGV(const char *prefix) const { mHal.state.type->dumpLOGV(s.string()); } - LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i", - prefix, mHal.state.mallocPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead); - - LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i", - prefix, mHal.state.usageFlags, mHal.state.mipmapControl, mTextureID, mBufferID); + LOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x", + prefix, getPtr(), mHal.state.usageFlags, mHal.state.mipmapControl); } void Allocation::serialize(OStream *stream) const { @@ -541,7 +213,7 @@ void Allocation::serialize(OStream *stream) const { // Write how much data we are storing stream->addU32(dataSize); // Now write the data - stream->addByteArray(mHal.state.mallocPtr, dataSize); + stream->addByteArray(getPtr(), dataSize); } Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { @@ -569,7 +241,7 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { return NULL; } - Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT); + Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT); alloc->setName(name.string(), name.size()); uint32_t count = dataSize / type->getElementSizeBytes(); @@ -581,12 +253,13 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { return alloc; } -void Allocation::sendDirty() const { +void Allocation::sendDirty(const Context *rsc) const { #ifndef ANDROID_RS_SERIALIZE for (size_t ct=0; ct < mToDirtyList.size(); ct++) { mToDirtyList[ct]->forceDirty(); } #endif //ANDROID_RS_SERIALIZE + mRSC->mHal.funcs.allocation.markDirty(rsc, this); } void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const { @@ -619,24 +292,16 @@ void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff } void Allocation::resize1D(Context *rsc, uint32_t dimX) { - Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX); - uint32_t oldDimX = mHal.state.dimensionX; if (dimX == oldDimX) { return; } + Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX); if (dimX < oldDimX) { - decRefs(mHal.state.mallocPtr, oldDimX - dimX, dimX); + decRefs(getPtr(), oldDimX - dimX, dimX); } - mHal.state.mallocPtr = realloc(mHal.state.mallocPtr, t->getSizeBytes()); - - if (dimX > oldDimX) { - const Element *e = mHal.state.type->getElement(); - uint32_t stride = e->getSizeBytes(); - memset(((uint8_t *)mHal.state.mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX)); - } - + rsc->mHal.funcs.allocation.resize(rsc, this, t, mHal.state.hasReferences); mHal.state.type.set(t); updateCache(); } @@ -655,16 +320,6 @@ namespace renderscript { static void AllocationGenerateScriptMips(RsContext con, RsAllocation va); -void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) { - Allocation *alloc = static_cast<Allocation *>(va); - alloc->deferredUploadToTexture(rsc); -} - -void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) { - Allocation *alloc = static_cast<Allocation *>(va); - alloc->deferredUploadToBufferObject(rsc); -} - static void mip565(const Adapter2D &out, const Adapter2D &in) { uint32_t w = out.getDimX(); uint32_t h = out.getDimY(); @@ -735,8 +390,8 @@ static void mip(const Adapter2D &out, const Adapter2D &in) { void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) { Allocation *a = static_cast<Allocation *>(va); + a->sendDirty(rsc); a->syncAll(rsc, src); - a->sendDirty(); } void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) { @@ -816,7 +471,10 @@ static void AllocationGenerateScriptMips(RsContext con, RsAllocation va) { RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype, RsAllocationMipmapControl mips, uint32_t usages) { - Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips); + Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips); + if (!alloc) { + return NULL; + } alloc->incUserRef(); return alloc; } @@ -838,7 +496,7 @@ RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype, AllocationGenerateScriptMips(rsc, texAlloc); } - texAlloc->deferredUploadToTexture(rsc); + texAlloc->sendDirty(rsc); return texAlloc; } @@ -878,7 +536,7 @@ RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype, AllocationGenerateScriptMips(rsc, texAlloc); } - texAlloc->deferredUploadToTexture(rsc); + texAlloc->sendDirty(rsc); return texAlloc; } diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index d334841..5cf6292 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -34,7 +34,6 @@ public: struct State { ObjectBaseRef<const Type> type; - void * mallocPtr; uint32_t usageFlags; RsAllocationMipmapControl mipmapControl; @@ -50,41 +49,25 @@ public: bool hasReferences; }; State state; + + struct DrvState { + void * mallocPtr; + } drvState; + }; Hal mHal; - Allocation(Context *rsc, const Type *, uint32_t usages, - RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE); + static Allocation * createAllocation(Context *rsc, const Type *, uint32_t usages, + RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE); virtual ~Allocation(); void updateCache(); - void setCpuWritable(bool); - void setGpuWritable(bool); - void setCpuReadable(bool); - void setGpuReadable(bool); - - bool fixAllocation(); - - void * getPtr() const {return mHal.state.mallocPtr;} + void * getPtr() const {return mHal.drvState.mallocPtr;} const Type * getType() const {return mHal.state.type.get();} void syncAll(Context *rsc, RsAllocationUsageType src); - void deferredUploadToTexture(const Context *rsc); - void uploadToTexture(const Context *rsc); - uint32_t getTextureID() const {return mTextureID;} - - void deferredAllocateRenderTarget(const Context *rsc); - void allocateRenderTarget(const Context *rsc); - uint32_t getRenderTargetID() const {return mRenderTargetID;} - - uint32_t getGLTarget() const; - - void deferredUploadToBufferObject(const Context *rsc); - void uploadToBufferObject(const Context *rsc); - uint32_t getBufferObjectID() const {return mBufferID;} - void copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len); void resize1D(Context *rsc, uint32_t dimX); @@ -103,9 +86,6 @@ public: void read(void *data); - void enableGLVertexBuffers() const; - void setupGLIndexBuffers() const; - void addProgramToDirty(const Program *); void removeProgramToDirty(const Program *); @@ -114,8 +94,6 @@ public: virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_ALLOCATION; } static Allocation *createFromStream(Context *rsc, IStream *stream); - virtual void uploadCheck(Context *rsc); - bool getIsScript() const { return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0; } @@ -132,7 +110,7 @@ public: void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const; void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const; - void sendDirty() const; + void sendDirty(const Context *rsc) const; bool getHasGraphicsMipmaps() const { return mHal.state.mipmapControl != RS_ALLOCATION_MIPMAP_NONE; } @@ -141,40 +119,9 @@ public: protected: Vector<const Program *> mToDirtyList; - // Is we have a non-null user bitmap callback we do not own the bits and - // instead call this function to free the memort when its time. - RsBitmapCallback_t mUserBitmapCallback; - void *mUserBitmapCallbackData; - - // Usage restrictions - bool mCpuWrite; - bool mCpuRead; - bool mGpuWrite; - bool mGpuRead; - - // more usage hint data from the application - // which can be used by a driver to pick the best memory type. - // Likely ignored for now - float mReadWriteRatio; - float mUpdateSize; - - - // Is this a legal structure to be used as a texture source. - // Initially this will require 1D or 2D and color data - uint32_t mTextureID; - - // Is this a legal structure to be used as a vertex source. - // Initially this will require 1D and x(yzw). Additional per element data - // is allowed. - uint32_t mBufferID; - - // Is this a legal structure to be used as an FBO render target - uint32_t mRenderTargetID; - - bool mUploadDeferred; - private: - void init(Context *rsc, const Type *); + Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc); + void upload2DTexture(bool isFirstUpload); void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h); diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index be615a3..4ba00fe 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -270,6 +270,13 @@ public: ObjectBase::zeroAllUserRef(this); } + struct Hal { + void * drv; + + RsdHalFunctions funcs; + }; + Hal mHal; + ElementState mStateElement; TypeState mStateType; diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp index 31a51b7..6960ef2 100644 --- a/libs/rs/rsFBOCache.cpp +++ b/libs/rs/rsFBOCache.cpp @@ -51,13 +51,6 @@ void FBOCache::bindColorTarget(Context *rsc, Allocation *a, uint32_t slot) { LOGE("Invalid Color Target"); return; } - if (a->getIsTexture()) { - if (a->getTextureID() == 0) { - a->deferredUploadToTexture(rsc); - } - } else if (a->getRenderTargetID() == 0) { - a->deferredAllocateRenderTarget(rsc); - } } mHal.state.colorTargets[slot].set(a); mDirty = true; @@ -69,13 +62,6 @@ void FBOCache::bindDepthTarget(Context *rsc, Allocation *a) { LOGE("Invalid Depth Target"); return; } - if (a->getIsTexture()) { - if (a->getTextureID() == 0) { - a->deferredUploadToTexture(rsc); - } - } else if (a->getRenderTargetID() == 0) { - a->deferredAllocateRenderTarget(rsc); - } } mHal.state.depthTarget.set(a); mDirty = true; @@ -95,12 +81,12 @@ void FBOCache::setup(Context *rsc) { } if (mHal.state.depthTarget.get() != NULL) { - mHal.state.depthTarget->uploadCheck(rsc); + mHal.state.depthTarget->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); } for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) { if (mHal.state.colorTargets[i].get() != NULL) { - mHal.state.colorTargets[i]->uploadCheck(rsc); + mHal.state.colorTargets[i]->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); } } diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 5e47ddb..b625504 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -452,7 +452,8 @@ bool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *r // This will dirty the texture and the shader so next time // we draw it will upload the data - mTextTexture->deferredUploadToTexture(mRSC); + + mTextTexture->sendDirty(mRSC); mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get()); // Some debug code @@ -490,7 +491,7 @@ void FontState::initRenderState() { tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE; tmp[3] = RS_TEXTURE_2D; - mFontShaderFConstant.set(new Allocation(mRSC, inputType, + mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)); ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), shaderString.length(), tmp, 4); @@ -517,7 +518,8 @@ void FontState::initTextTexture() { // We will allocate a texture to initially hold 32 character bitmaps Type *texType = Type::getType(mRSC, alphaElem, 1024, 256, 0, false, false); - Allocation *cacheAlloc = new Allocation(mRSC, texType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE); + Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType, + RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE); mTextTexture.set(cacheAlloc); mTextTexture->syncAll(mRSC, RS_ALLOCATION_USAGE_SCRIPT); @@ -545,7 +547,9 @@ void FontState::initVertexArrayBuffers() { uint32_t numIndicies = mMaxNumberOfQuads * 6; Type *indexType = Type::getType(mRSC, indexElem, numIndicies, 0, 0, false, false); - Allocation *indexAlloc = new Allocation(mRSC, indexType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_VERTEX); + Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType, + RS_ALLOCATION_USAGE_SCRIPT | + RS_ALLOCATION_USAGE_GRAPHICS_VERTEX); uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr(); // Four verts, two triangles , six indices per quad @@ -562,7 +566,7 @@ void FontState::initVertexArrayBuffers() { indexPtr[i6 + 5] = i4 + 3; } - indexAlloc->deferredUploadToBufferObject(mRSC); + indexAlloc->sendDirty(mRSC); const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2); @@ -576,7 +580,8 @@ void FontState::initVertexArrayBuffers() { mMaxNumberOfQuads * 4, 0, 0, false, false); - Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_VERTEX); + Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType, + RS_ALLOCATION_USAGE_SCRIPT); mTextMeshPtr = (float*)vertexAlloc->getPtr(); mMesh.set(new Mesh(mRSC, 1, 1)); diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp index 3d0342d..62e388c 100644 --- a/libs/rs/rsMesh.cpp +++ b/libs/rs/rsMesh.cpp @@ -191,28 +191,19 @@ void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start return; } - for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) { - mHal.state.vertexBuffers[ct]->uploadCheck(rsc); - } - - Primitive_t *prim = mHal.state.primitives[primIndex]; - if (prim->mIndexBuffer.get()) { - prim->mIndexBuffer->uploadCheck(rsc); - } - mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len); } void Mesh::uploadAll(Context *rsc) { for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) { if (mHal.state.vertexBuffers[ct].get()) { - mHal.state.vertexBuffers[ct]->deferredUploadToBufferObject(rsc); + rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.vertexBuffers[ct].get()); } } for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) { if (mHal.state.primitives[ct]->mIndexBuffer.get()) { - mHal.state.primitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc); + rsc->mHal.funcs.allocation.markDirty(rsc, mHal.state.primitives[ct]->mIndexBuffer.get()); } } } diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index e40fc7b..0823d82 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -67,7 +67,6 @@ void ProgramFragment::setup(Context *rsc, ProgramFragmentState *state) { rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound"); continue; } - mHal.state.textures[ct]->uploadCheck(rsc); } rsc->mHal.funcs.fragment.setActive(rsc, this); @@ -109,7 +108,8 @@ void ProgramFragmentState::init(Context *rsc) { tmp[0] = RS_PROGRAM_PARAM_CONSTANT; tmp[1] = (uint32_t)inputType; - Allocation *constAlloc = new Allocation(rsc, inputType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); + Allocation *constAlloc = Allocation::createAllocation(rsc, inputType, + RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), shaderString.length(), tmp, 2); pf->bindAllocation(rsc, constAlloc, 0); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 534e8a6..e6790cb 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -189,7 +189,8 @@ void ProgramVertexState::init(Context *rsc) { ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), shaderString.length(), tmp, 4); - Allocation *alloc = new Allocation(rsc, inputType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); + Allocation *alloc = Allocation::createAllocation(rsc, inputType, + RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); pv->bindAllocation(rsc, alloc, 0); mDefaultAlloc.set(alloc); diff --git a/libs/rs/rsRuntime.h b/libs/rs/rsRuntime.h index 884f7b6..6d45285 100644 --- a/libs/rs/rsRuntime.h +++ b/libs/rs/rsRuntime.h @@ -125,6 +125,12 @@ void rsrSetObject(const Context *, const Script *, ObjectBase **dst, ObjectBase void rsrClearObject(const Context *, const Script *, ObjectBase **dst); bool rsrIsObject(const Context *, const Script *, const ObjectBase *src); +void rsrAllocationIncRefs(const Context *, const Allocation *, void *ptr, + size_t elementCount, size_t startOffset); +void rsrAllocationDecRefs(const Context *, const Allocation *, void *ptr, + size_t elementCount, size_t startOffset); + + uint32_t rsrToClient(Context *, Script *, int cmdID, void *data, int len); uint32_t rsrToClientBlocking(Context *, Script *, int cmdID, void *data, int len); const Allocation * rsrGetAllocation(Context *, Script *, const void *ptr); diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h index 9d8c906..44c7e71 100644 --- a/libs/rs/rs_hal.h +++ b/libs/rs/rs_hal.h @@ -93,6 +93,35 @@ typedef struct { } script; struct { + bool (*init)(const Context *rsc, Allocation *alloc, bool forceZero); + void (*destroy)(const Context *rsc, Allocation *alloc); + + void (*resize)(const Context *rsc, const Allocation *alloc, const Type *newType, + bool zeroNew); + void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src); + void (*markDirty)(const Context *rsc, const Allocation *alloc); + + void (*data1D)(const Context *rsc, const Allocation *alloc, + uint32_t xoff, uint32_t lod, uint32_t count, + const void *data, uint32_t sizeBytes); + void (*data2D)(const Context *rsc, const Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t lod, + RsAllocationCubemapFace face, uint32_t w, uint32_t h, + const void *data, uint32_t sizeBytes); + void (*data3D)(const Context *rsc, const Allocation *alloc, + uint32_t xoff, uint32_t yoff, uint32_t zoff, + uint32_t lod, RsAllocationCubemapFace face, + uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes); + + void (*elementData1D)(const Context *rsc, const Allocation *alloc, uint32_t x, + const void *data, uint32_t elementOff, uint32_t sizeBytes); + void (*elementData2D)(const Context *rsc, const Allocation *alloc, uint32_t x, uint32_t y, + const void *data, uint32_t elementOff, uint32_t sizeBytes); + + + } allocation; + + struct { bool (*init)(const Context *rsc, const ProgramStore *ps); void (*setActive)(const Context *rsc, const ProgramStore *ps); void (*destroy)(const Context *rsc, const ProgramStore *ps); |