diff options
-rw-r--r-- | libs/rs/Android.mk | 1 | ||||
-rw-r--r-- | libs/rs/driver/rsdCore.cpp | 7 | ||||
-rw-r--r-- | libs/rs/driver/rsdFrameBuffer.cpp | 162 | ||||
-rw-r--r-- | libs/rs/driver/rsdFrameBuffer.h | 30 | ||||
-rw-r--r-- | libs/rs/rsContext.cpp | 2 | ||||
-rw-r--r-- | libs/rs/rsFBOCache.cpp | 150 | ||||
-rw-r--r-- | libs/rs/rsFBOCache.h | 21 | ||||
-rw-r--r-- | libs/rs/rs_hal.h | 7 |
8 files changed, 249 insertions, 131 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index ef00b30..29c1447 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -117,6 +117,7 @@ LOCAL_SRC_FILES:= \ rsType.cpp \ driver/rsdBcc.cpp \ driver/rsdCore.cpp \ + driver/rsdFrameBuffer.cpp \ driver/rsdGL.cpp \ driver/rsdMesh.cpp \ driver/rsdMeshObj.cpp \ diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp index 0a5f2ec..7ef9c30 100644 --- a/libs/rs/driver/rsdCore.cpp +++ b/libs/rs/driver/rsdCore.cpp @@ -23,6 +23,7 @@ #include "rsdProgramFragment.h" #include "rsdMesh.h" #include "rsdSampler.h" +#include "rsdFrameBuffer.h" #include <malloc.h> #include "rsContext.h" @@ -98,6 +99,12 @@ static RsdHalFunctions FunctionTable = { rsdSamplerDestroy }, + { + rsdFrameBufferInit, + rsdFrameBufferSetActive, + rsdFrameBufferDestroy + }, + }; pthread_key_t rsdgThreadTLSKey = 0; diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp new file mode 100644 index 0000000..6a7dac4 --- /dev/null +++ b/libs/rs/driver/rsdFrameBuffer.cpp @@ -0,0 +1,162 @@ +/* + * 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 "rsdFrameBuffer.h" + +#include "rsContext.h" +#include "rsFBOCache.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +using namespace android; +using namespace android::renderscript; + +struct DrvFrameBuffer { + GLuint mFBOId; +}; + +void checkError(const Context *rsc) { + GLenum status; + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch (status) { + case GL_FRAMEBUFFER_COMPLETE: + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + rsc->setError(RS_ERROR_BAD_VALUE, + "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); + break; + } +} + + +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(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, texID, 0); + } else { + uint32_t texID = fb->mHal.state.depthTarget->getRenderTargetID(); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, texID); + } + } else { + // Reset last attachment + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, 0, 0); + } +} + +void setColorAttachment(const Context *rsc, const FBOCache *fb) { + // Now attach color targets + 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(); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, texID, 0); + } else { + uint32_t texID = fb->mHal.state.depthTarget->getRenderTargetID(); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_RENDERBUFFER, texID); + } + } else { + // Reset last attachment + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_RENDERBUFFER, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, 0, 0); + } + } +} + +bool renderToFramebuffer(const FBOCache *fb) { + if (fb->mHal.state.depthTarget.get() != NULL) { + return false; + } + + for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { + if (fb->mHal.state.colorTargets[i].get() != NULL) { + return false; + } + } + return true; +} + + +bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) { + DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer)); + if (drv == NULL) { + return false; + } + fb->mHal.drv = drv; + drv->mFBOId = 0; + + return true; +} + +void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) { + DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; + + bool framebuffer = renderToFramebuffer(fb); + if (!framebuffer) { + if(drv->mFBOId == 0) { + glGenFramebuffers(1, &drv->mFBOId); + } + glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId); + + setDepthAttachment(rsc, fb); + setColorAttachment(rsc, fb); + + glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(), + fb->mHal.state.colorTargets[0]->getType()->getDimY()); + + checkError(rsc); + } else { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); + } +} + +void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { + DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; + if(drv->mFBOId != 0) { + glDeleteFramebuffers(1, &drv->mFBOId); + } + + free(fb->mHal.drv); + fb->mHal.drv = NULL; +} + + diff --git a/libs/rs/driver/rsdFrameBuffer.h b/libs/rs/driver/rsdFrameBuffer.h new file mode 100644 index 0000000..dec59fc --- /dev/null +++ b/libs/rs/driver/rsdFrameBuffer.h @@ -0,0 +1,30 @@ +/* + * 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_FRAME_BUFFER_H +#define RSD_FRAME_BUFFER_H + +#include <rs_hal.h> + +bool rsdFrameBufferInit(const android::renderscript::Context *rsc, + const android::renderscript::FBOCache *fb); +void rsdFrameBufferSetActive(const android::renderscript::Context *rsc, + const android::renderscript::FBOCache *fb); +void rsdFrameBufferDestroy(const android::renderscript::Context *rsc, + const android::renderscript::FBOCache *fb); + + +#endif // RSD_FRAME_BUFFER_H diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 98adabc..532b1a2 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -238,6 +238,7 @@ void * Context::threadProc(void *vrsc) { rsc->setProgramStore(NULL); rsc->mStateFont.init(rsc); rsc->setFont(NULL); + rsc->mFBOCache.init(rsc); } rsc->mRunning = true; @@ -298,6 +299,7 @@ void Context::destroyWorkerThreadResources() { mStateFragment.deinit(this); mStateFragmentStore.deinit(this); mStateFont.deinit(this); + mFBOCache.deinit(this); } //LOGV("destroyWorkerThreadResources 2"); mExit = true; diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp index 0f33f67..31a51b7 100644 --- a/libs/rs/rsFBOCache.cpp +++ b/libs/rs/rsFBOCache.cpp @@ -19,33 +19,30 @@ #include "rsContext.h" #include "rsAllocation.h" -#ifndef ANDROID_RS_SERIALIZE -#include <GLES/gl.h> -#include <GLES2/gl2.h> -#endif //ANDROID_RS_SERIALIZE - using namespace android; using namespace android::renderscript; FBOCache::FBOCache() { - mFBOId = 0; mDirty = true; - mMaxTargets = 1; - mColorTargets = new ObjectBaseRef<Allocation>[mMaxTargets]; + mHal.state.colorTargetsCount = 1; + mHal.state.colorTargets = new ObjectBaseRef<Allocation>[mHal.state.colorTargetsCount]; } FBOCache::~FBOCache() { - delete[] mColorTargets; -#ifndef ANDROID_RS_SERIALIZE - if(mFBOId != 0) { - glDeleteFramebuffers(1, &mFBOId); - } -#endif //ANDROID_RS_SERIALIZE + delete[] mHal.state.colorTargets; +} + +void FBOCache::init(Context *rsc) { + rsc->mHal.funcs.framebuffer.init(rsc, this); +} + +void FBOCache::deinit(Context *rsc) { + rsc->mHal.funcs.framebuffer.destroy(rsc, this); } void FBOCache::bindColorTarget(Context *rsc, Allocation *a, uint32_t slot) { - if (slot >= mMaxTargets) { + if (slot >= mHal.state.colorTargetsCount) { LOGE("Invalid render target index"); return; } @@ -62,7 +59,7 @@ void FBOCache::bindColorTarget(Context *rsc, Allocation *a, uint32_t slot) { a->deferredAllocateRenderTarget(rsc); } } - mColorTargets[slot].set(a); + mHal.state.colorTargets[slot].set(a); mDirty = true; } @@ -80,131 +77,34 @@ void FBOCache::bindDepthTarget(Context *rsc, Allocation *a) { a->deferredAllocateRenderTarget(rsc); } } - mDepthTarget.set(a); + mHal.state.depthTarget.set(a); mDirty = true; } void FBOCache::resetAll(Context *) { - for (uint32_t i = 0; i < mMaxTargets; i ++) { - mColorTargets[i].set(NULL); + for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) { + mHal.state.colorTargets[i].set(NULL); } - mDepthTarget.set(NULL); + mHal.state.depthTarget.set(NULL); mDirty = true; } -bool FBOCache::renderToFramebuffer() { - if (mDepthTarget.get() != NULL) { - return false; - } - - for (uint32_t i = 0; i < mMaxTargets; i ++) { - if (mColorTargets[i].get() != NULL) { - return false; - } - } - return true; -} - -void FBOCache::checkError(Context *rsc) { - GLenum status; - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) { - case GL_FRAMEBUFFER_COMPLETE: - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - rsc->setError(RS_ERROR_BAD_VALUE, - "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); - break; - } -} - -void FBOCache::setDepthAttachment(Context *rsc) { -#ifndef ANDROID_RS_SERIALIZE - if (mDepthTarget.get() != NULL) { - mDepthTarget->uploadCheck(rsc); - if (mDepthTarget->getIsTexture()) { - uint32_t texID = mDepthTarget->getTextureID(); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, texID, 0); - } else { - uint32_t texID = mDepthTarget->getRenderTargetID(); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, texID); - } - } else { - // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, 0, 0); - } -#endif //ANDROID_RS_SERIALIZE -} - -void FBOCache::setColorAttachment(Context *rsc) { -#ifndef ANDROID_RS_SERIALIZE - // Now attach color targets - for (uint32_t i = 0; i < mMaxTargets; i ++) { - uint32_t texID = 0; - if (mColorTargets[i].get() != NULL) { - mColorTargets[i]->uploadCheck(rsc); - if (mColorTargets[i]->getIsTexture()) { - uint32_t texID = mColorTargets[i]->getTextureID(); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, texID, 0); - } else { - uint32_t texID = mDepthTarget->getRenderTargetID(); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, texID); - } - } else { - // Reset last attachment - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_RENDERBUFFER, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, - GL_TEXTURE_2D, 0, 0); - } - } -#endif //ANDROID_RS_SERIALIZE -} - void FBOCache::setup(Context *rsc) { -#ifndef ANDROID_RS_SERIALIZE if (!mDirty) { return; } - bool framebuffer = renderToFramebuffer(); + if (mHal.state.depthTarget.get() != NULL) { + mHal.state.depthTarget->uploadCheck(rsc); + } - if (!framebuffer) { - if(mFBOId == 0) { - glGenFramebuffers(1, &mFBOId); + for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) { + if (mHal.state.colorTargets[i].get() != NULL) { + mHal.state.colorTargets[i]->uploadCheck(rsc); } - glBindFramebuffer(GL_FRAMEBUFFER, mFBOId); - - setDepthAttachment(rsc); - setColorAttachment(rsc); + } - glViewport(0, 0, mColorTargets[0]->getType()->getDimX(), - mColorTargets[0]->getType()->getDimY()); + rsc->mHal.funcs.framebuffer.setActive(rsc, this); - checkError(rsc); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); - } mDirty = false; -#endif //ANDROID_RS_SERIALIZE } diff --git a/libs/rs/rsFBOCache.h b/libs/rs/rsFBOCache.h index c9ae1dc..f42e1f3 100644 --- a/libs/rs/rsFBOCache.h +++ b/libs/rs/rsFBOCache.h @@ -30,24 +30,33 @@ public: FBOCache(); ~FBOCache(); + void init(Context *rsc); + void deinit(Context *rsc); + void bindColorTarget(Context *rsc, Allocation *a, uint32_t slot); void bindDepthTarget(Context *, Allocation *a); void resetAll(Context *); void setup(Context *); -protected: + struct Hal { + mutable void *drv; + + struct State { + ObjectBaseRef<Allocation> *colorTargets; + uint32_t colorTargetsCount; + ObjectBaseRef<Allocation> depthTarget; + }; + State state; + }; + Hal mHal; +protected: bool mDirty; - uint32_t mMaxTargets; void checkError(Context *); void setColorAttachment(Context *rsc); void setDepthAttachment(Context *rsc); bool renderToFramebuffer(); - ObjectBaseRef<Allocation> *mColorTargets; - ObjectBaseRef<Allocation> mDepthTarget; - - uint32_t mFBOId; }; diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h index 4cc2abf..cfa4e74 100644 --- a/libs/rs/rs_hal.h +++ b/libs/rs/rs_hal.h @@ -37,6 +37,7 @@ class ProgramVertex; class ProgramFragment; class Mesh; class Sampler; +class FBOCache; typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName); @@ -128,6 +129,12 @@ typedef struct { void (*destroy)(const Context *rsc, const Sampler *m); } sampler; + struct { + bool (*init)(const Context *rsc, const FBOCache *fb); + void (*setActive)(const Context *rsc, const FBOCache *fb); + void (*destroy)(const Context *rsc, const FBOCache *fb); + } framebuffer; + } RsdHalFunctions; |