First draft of fbo in renderscript.
Updating samples and benchmark Change-Id: I469bf8b842fca72b59475c8fa024c12cf0e14954
This commit is contained in:
@ -99,6 +99,14 @@ public class Allocation extends BaseObj {
|
||||
*/
|
||||
public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
|
||||
* target for offscreen rendering
|
||||
*
|
||||
*/
|
||||
public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
|
||||
|
||||
|
||||
/**
|
||||
* Controls mipmap behavior when using the bitmap creation and
|
||||
@ -137,7 +145,8 @@ public class Allocation extends BaseObj {
|
||||
if ((usage & ~(USAGE_SCRIPT |
|
||||
USAGE_GRAPHICS_TEXTURE |
|
||||
USAGE_GRAPHICS_VERTEX |
|
||||
USAGE_GRAPHICS_CONSTANTS)) != 0) {
|
||||
USAGE_GRAPHICS_CONSTANTS |
|
||||
USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
|
||||
throw new RSIllegalArgumentException("Unknown usage specified.");
|
||||
}
|
||||
mType = t;
|
||||
|
@ -124,7 +124,8 @@ public class Element extends BaseObj {
|
||||
PIXEL_A (8),
|
||||
PIXEL_LA (9),
|
||||
PIXEL_RGB (10),
|
||||
PIXEL_RGBA (11);
|
||||
PIXEL_RGBA (11),
|
||||
PIXEL_DEPTH (12);
|
||||
|
||||
int mID;
|
||||
DataKind(int id) {
|
||||
@ -536,10 +537,12 @@ public class Element extends BaseObj {
|
||||
dk == DataKind.PIXEL_A ||
|
||||
dk == DataKind.PIXEL_LA ||
|
||||
dk == DataKind.PIXEL_RGB ||
|
||||
dk == DataKind.PIXEL_RGBA)) {
|
||||
dk == DataKind.PIXEL_RGBA ||
|
||||
dk == DataKind.PIXEL_DEPTH)) {
|
||||
throw new RSIllegalArgumentException("Unsupported DataKind");
|
||||
}
|
||||
if (!(dt == DataType.UNSIGNED_8 ||
|
||||
dt == DataType.UNSIGNED_16 ||
|
||||
dt == DataType.UNSIGNED_5_6_5 ||
|
||||
dt == DataType.UNSIGNED_4_4_4_4 ||
|
||||
dt == DataType.UNSIGNED_5_5_5_1)) {
|
||||
@ -554,16 +557,25 @@ public class Element extends BaseObj {
|
||||
if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
|
||||
throw new RSIllegalArgumentException("Bad kind and type combo");
|
||||
}
|
||||
if (dt == DataType.UNSIGNED_16 &&
|
||||
dk != DataKind.PIXEL_DEPTH) {
|
||||
throw new RSIllegalArgumentException("Bad kind and type combo");
|
||||
}
|
||||
|
||||
int size = 1;
|
||||
if (dk == DataKind.PIXEL_LA) {
|
||||
switch (dk) {
|
||||
case PIXEL_LA:
|
||||
size = 2;
|
||||
}
|
||||
if (dk == DataKind.PIXEL_RGB) {
|
||||
break;
|
||||
case PIXEL_RGB:
|
||||
size = 3;
|
||||
}
|
||||
if (dk == DataKind.PIXEL_RGBA) {
|
||||
break;
|
||||
case PIXEL_RGBA:
|
||||
size = 4;
|
||||
break;
|
||||
case PIXEL_DEPTH:
|
||||
size = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean norm = true;
|
||||
|
@ -90,6 +90,7 @@ LOCAL_SRC_FILES:= \
|
||||
rsContext.cpp \
|
||||
rsDevice.cpp \
|
||||
rsElement.cpp \
|
||||
rsFBOCache.cpp \
|
||||
rsFileA3D.cpp \
|
||||
rsFont.cpp \
|
||||
rsLocklessFifo.cpp \
|
||||
|
@ -84,6 +84,7 @@ enum RsAllocationUsageType {
|
||||
RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE = 0x0002,
|
||||
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
|
||||
RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
|
||||
RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
|
||||
|
||||
RS_ALLOCATION_USAGE_ALL = 0x000F
|
||||
};
|
||||
@ -147,6 +148,7 @@ enum RsDataKind {
|
||||
RS_KIND_PIXEL_LA,
|
||||
RS_KIND_PIXEL_RGB,
|
||||
RS_KIND_PIXEL_RGBA,
|
||||
RS_KIND_PIXEL_DEPTH,
|
||||
};
|
||||
|
||||
enum RsSamplerParam {
|
||||
|
@ -56,7 +56,8 @@ void Allocation::init(Context *rsc, const Type *type) {
|
||||
|
||||
mTextureID = 0;
|
||||
mBufferID = 0;
|
||||
mUploadDefered = false;
|
||||
mRenderTargetID = 0;
|
||||
mUploadDeferred = false;
|
||||
|
||||
mUserBitmapCallback = NULL;
|
||||
mUserBitmapCallbackData = NULL;
|
||||
@ -93,6 +94,10 @@ Allocation::~Allocation() {
|
||||
glDeleteTextures(1, &mTextureID);
|
||||
mTextureID = 0;
|
||||
}
|
||||
if (mRenderTargetID) {
|
||||
glDeleteRenderbuffers(1, &mRenderTargetID);
|
||||
mRenderTargetID = 0;
|
||||
}
|
||||
#endif //ANDROID_RS_SERIALIZE
|
||||
}
|
||||
|
||||
@ -112,9 +117,14 @@ bool Allocation::fixAllocation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Allocation::deferedUploadToTexture(const Context *rsc) {
|
||||
void Allocation::deferredUploadToTexture(const Context *rsc) {
|
||||
mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
}
|
||||
|
||||
void Allocation::deferredAllocateRenderTarget(const Context *rsc) {
|
||||
mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
|
||||
mUploadDeferred = true;
|
||||
}
|
||||
|
||||
uint32_t Allocation::getGLTarget() const {
|
||||
@ -155,8 +165,11 @@ void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
|
||||
if (getIsBufferObject()) {
|
||||
uploadToBufferObject(rsc);
|
||||
}
|
||||
if (getIsRenderTarget() && !getIsTexture()) {
|
||||
allocateRenderTarget(rsc);
|
||||
}
|
||||
|
||||
mUploadDefered = false;
|
||||
mUploadDeferred = false;
|
||||
}
|
||||
|
||||
void Allocation::uploadToTexture(const Context *rsc) {
|
||||
@ -184,7 +197,7 @@ void Allocation::uploadToTexture(const Context *rsc) {
|
||||
// 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();
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
return;
|
||||
}
|
||||
isFirstUpload = true;
|
||||
@ -200,6 +213,32 @@ void Allocation::uploadToTexture(const Context *rsc) {
|
||||
#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,
|
||||
@ -271,9 +310,9 @@ void Allocation::upload2DTexture(bool isFirstUpload) {
|
||||
#endif //ANDROID_RS_SERIALIZE
|
||||
}
|
||||
|
||||
void Allocation::deferedUploadToBufferObject(const Context *rsc) {
|
||||
void Allocation::deferredUploadToBufferObject(const Context *rsc) {
|
||||
mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
}
|
||||
|
||||
void Allocation::uploadToBufferObject(const Context *rsc) {
|
||||
@ -288,7 +327,7 @@ void Allocation::uploadToBufferObject(const Context *rsc) {
|
||||
}
|
||||
if (!mBufferID) {
|
||||
LOGE("Upload to buffer object failed");
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
return;
|
||||
}
|
||||
GLenum target = (GLenum)getGLTarget();
|
||||
@ -300,7 +339,7 @@ void Allocation::uploadToBufferObject(const Context *rsc) {
|
||||
}
|
||||
|
||||
void Allocation::uploadCheck(Context *rsc) {
|
||||
if (mUploadDefered) {
|
||||
if (mUploadDeferred) {
|
||||
syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
|
||||
}
|
||||
}
|
||||
@ -329,7 +368,7 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
|
||||
|
||||
memcpy(ptr, data, size);
|
||||
sendDirty();
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
}
|
||||
|
||||
void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
|
||||
@ -362,7 +401,7 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod,
|
||||
dst += destW * eSize;
|
||||
}
|
||||
sendDirty();
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
} else {
|
||||
update2DTexture(data, xoff, yoff, lod, face, w, h);
|
||||
}
|
||||
@ -407,7 +446,7 @@ void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
|
||||
|
||||
memcpy(ptr, data, sizeBytes);
|
||||
sendDirty();
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
}
|
||||
|
||||
void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
|
||||
@ -450,7 +489,7 @@ void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
|
||||
|
||||
memcpy(ptr, data, sizeBytes);
|
||||
sendDirty();
|
||||
mUploadDefered = true;
|
||||
mUploadDeferred = true;
|
||||
}
|
||||
|
||||
void Allocation::addProgramToDirty(const Program *p) {
|
||||
@ -617,12 +656,12 @@ namespace renderscript {
|
||||
|
||||
void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
|
||||
Allocation *alloc = static_cast<Allocation *>(va);
|
||||
alloc->deferedUploadToTexture(rsc);
|
||||
alloc->deferredUploadToTexture(rsc);
|
||||
}
|
||||
|
||||
void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
|
||||
Allocation *alloc = static_cast<Allocation *>(va);
|
||||
alloc->deferedUploadToBufferObject(rsc);
|
||||
alloc->deferredUploadToBufferObject(rsc);
|
||||
}
|
||||
|
||||
static void mip565(const Adapter2D &out, const Adapter2D &in) {
|
||||
@ -792,7 +831,6 @@ RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
|
||||
return alloc;
|
||||
}
|
||||
|
||||
|
||||
RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
|
||||
RsAllocationMipmapControl mips,
|
||||
const void *data, uint32_t usages) {
|
||||
@ -811,7 +849,7 @@ RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
|
||||
rsaAllocationGenerateScriptMips(rsc, texAlloc);
|
||||
}
|
||||
|
||||
texAlloc->deferedUploadToTexture(rsc);
|
||||
texAlloc->deferredUploadToTexture(rsc);
|
||||
return texAlloc;
|
||||
}
|
||||
|
||||
@ -852,7 +890,7 @@ RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
|
||||
rsaAllocationGenerateScriptMips(rsc, texAlloc);
|
||||
}
|
||||
|
||||
texAlloc->deferedUploadToTexture(rsc);
|
||||
texAlloc->deferredUploadToTexture(rsc);
|
||||
return texAlloc;
|
||||
}
|
||||
|
||||
|
@ -71,13 +71,17 @@ public:
|
||||
|
||||
void syncAll(Context *rsc, RsAllocationUsageType src);
|
||||
|
||||
void deferedUploadToTexture(const Context *rsc);
|
||||
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 deferedUploadToBufferObject(const Context *rsc);
|
||||
void deferredUploadToBufferObject(const Context *rsc);
|
||||
void uploadToBufferObject(const Context *rsc);
|
||||
uint32_t getBufferObjectID() const {return mBufferID;}
|
||||
|
||||
@ -118,6 +122,9 @@ public:
|
||||
bool getIsTexture() const {
|
||||
return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
|
||||
}
|
||||
bool getIsRenderTarget() const {
|
||||
return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) != 0;
|
||||
}
|
||||
bool getIsBufferObject() const {
|
||||
return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
|
||||
}
|
||||
@ -161,7 +168,10 @@ protected:
|
||||
// is allowed.
|
||||
uint32_t mBufferID;
|
||||
|
||||
bool mUploadDefered;
|
||||
// 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 *);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#ifndef ANDROID_RS_SERIALIZE
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#endif
|
||||
|
||||
using namespace android;
|
||||
@ -207,6 +208,7 @@ uint32_t Component::getGLFormat() const {
|
||||
case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
|
||||
case RS_KIND_PIXEL_RGB: return GL_RGB;
|
||||
case RS_KIND_PIXEL_RGBA: return GL_RGBA;
|
||||
case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
|
||||
default: break;
|
||||
}
|
||||
#endif //ANDROID_RS_SERIALIZE
|
||||
|
@ -409,6 +409,7 @@ bool Context::setupCheck() {
|
||||
mFragment->setupGL2(this, &mStateFragment, &mShaderCache);
|
||||
mRaster->setupGL2(this, &mStateRaster);
|
||||
mVertex->setupGL2(this, &mStateVertex, &mShaderCache);
|
||||
mFBOCache.setupGL2(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "rsProgramRaster.h"
|
||||
#include "rsProgramVertex.h"
|
||||
#include "rsShaderCache.h"
|
||||
#include "rsFBOCache.h"
|
||||
#include "rsVertexArray.h"
|
||||
|
||||
#include "rsgApiStructs.h"
|
||||
@ -119,6 +120,7 @@ public:
|
||||
|
||||
ScriptCState mScriptC;
|
||||
ShaderCache mShaderCache;
|
||||
FBOCache mFBOCache;
|
||||
|
||||
void swapBuffers();
|
||||
void setRootScript(Script *);
|
||||
|
209
libs/rs/rsFBOCache.cpp
Normal file
209
libs/rs/rsFBOCache.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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 "rsFBOCache.h"
|
||||
|
||||
#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 = false;
|
||||
mMaxTargets = 1;
|
||||
mColorTargets = new ObjectBaseRef<Allocation>[mMaxTargets];
|
||||
}
|
||||
|
||||
FBOCache::~FBOCache() {
|
||||
delete[] mColorTargets;
|
||||
#ifndef ANDROID_RS_SERIALIZE
|
||||
if(mFBOId != 0) {
|
||||
glDeleteFramebuffers(1, &mFBOId);
|
||||
}
|
||||
#endif //ANDROID_RS_SERIALIZE
|
||||
}
|
||||
|
||||
void FBOCache::bindColorTarget(Context *rsc, Allocation *a, uint32_t slot) {
|
||||
if (slot >= mMaxTargets) {
|
||||
LOGE("Invalid render target index");
|
||||
return;
|
||||
}
|
||||
if (a != NULL) {
|
||||
if (!a->getIsTexture()) {
|
||||
LOGE("Invalid Color Target");
|
||||
return;
|
||||
}
|
||||
if (a->getIsTexture()) {
|
||||
if (a->getTextureID() == 0) {
|
||||
a->deferredUploadToTexture(rsc);
|
||||
}
|
||||
} else if (a->getRenderTargetID() == 0) {
|
||||
a->deferredAllocateRenderTarget(rsc);
|
||||
}
|
||||
}
|
||||
mColorTargets[slot].set(a);
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
void FBOCache::bindDepthTarget(Context *rsc, Allocation *a) {
|
||||
if (a != NULL) {
|
||||
if (!a->getIsRenderTarget()) {
|
||||
LOGE("Invalid Depth Target");
|
||||
return;
|
||||
}
|
||||
if (a->getIsTexture()) {
|
||||
if (a->getTextureID() == 0) {
|
||||
a->deferredUploadToTexture(rsc);
|
||||
}
|
||||
} else if (a->getRenderTargetID() == 0) {
|
||||
a->deferredAllocateRenderTarget(rsc);
|
||||
}
|
||||
}
|
||||
mDepthTarget.set(a);
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
void FBOCache::resetAll(Context *) {
|
||||
for (uint32_t i = 0; i < mMaxTargets; i ++) {
|
||||
mColorTargets[i].set(NULL);
|
||||
}
|
||||
mDepthTarget.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::setupGL2(Context *rsc) {
|
||||
#ifndef ANDROID_RS_SERIALIZE
|
||||
if (!mDirty) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool framebuffer = renderToFramebuffer();
|
||||
|
||||
if (!framebuffer) {
|
||||
if(mFBOId == 0) {
|
||||
glGenFramebuffers(1, &mFBOId);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBOId);
|
||||
|
||||
setDepthAttachment(rsc);
|
||||
setColorAttachment(rsc);
|
||||
|
||||
glViewport(0, 0, mColorTargets[0]->getType()->getDimX(),
|
||||
mColorTargets[0]->getType()->getDimY());
|
||||
|
||||
checkError(rsc);
|
||||
} else {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, rsc->getWidth(), rsc->getHeight());
|
||||
}
|
||||
#endif //ANDROID_RS_SERIALIZE
|
||||
}
|
57
libs/rs/rsFBOCache.h
Normal file
57
libs/rs/rsFBOCache.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 ANDROID_FRAME_BUFFER_OBJECT_CACHE_H
|
||||
#define ANDROID_FRAME_BUFFER_OBJECT_CACHE_H
|
||||
|
||||
#include "rsObjectBase.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
namespace renderscript {
|
||||
|
||||
class Allocation;
|
||||
|
||||
class FBOCache {
|
||||
public:
|
||||
FBOCache();
|
||||
~FBOCache();
|
||||
|
||||
void bindColorTarget(Context *rsc, Allocation *a, uint32_t slot);
|
||||
void bindDepthTarget(Context *, Allocation *a);
|
||||
void resetAll(Context *);
|
||||
|
||||
void setupGL2(Context *);
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
} // renderscript
|
||||
} // android
|
||||
|
||||
#endif //ANDROID_FRAME_BUFFER_OBJECT_CACHE_H
|
@ -566,7 +566,7 @@ void FontState::initVertexArrayBuffers() {
|
||||
indexPtr[i6 + 5] = i4 + 3;
|
||||
}
|
||||
|
||||
indexAlloc->deferedUploadToBufferObject(mRSC);
|
||||
indexAlloc->deferredUploadToBufferObject(mRSC);
|
||||
mIndexBuffer.set(indexAlloc);
|
||||
|
||||
const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
|
||||
|
@ -282,13 +282,13 @@ void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start
|
||||
void Mesh::uploadAll(Context *rsc) {
|
||||
for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
|
||||
if (mVertexBuffers[ct].get()) {
|
||||
mVertexBuffers[ct]->deferedUploadToBufferObject(rsc);
|
||||
mVertexBuffers[ct]->deferredUploadToBufferObject(rsc);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
|
||||
if (mPrimitives[ct]->mIndexBuffer.get()) {
|
||||
mPrimitives[ct]->mIndexBuffer->deferedUploadToBufferObject(rsc);
|
||||
mPrimitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,33 @@ static void SC_bindProgramRaster(RsProgramRaster pv) {
|
||||
rsi_ContextBindProgramRaster(rsc, pv);
|
||||
}
|
||||
|
||||
static void SC_bindFrameBufferObjectColorTarget(RsAllocation va, uint32_t slot) {
|
||||
CHECK_OBJ(va);
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.bindColorTarget(rsc, static_cast<Allocation *>(va), slot);
|
||||
}
|
||||
|
||||
static void SC_bindFrameBufferObjectDepthTarget(RsAllocation va) {
|
||||
CHECK_OBJ(va);
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.bindDepthTarget(rsc, static_cast<Allocation *>(va));
|
||||
}
|
||||
|
||||
static void SC_clearFrameBufferObjectColorTarget(uint32_t slot) {
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.bindColorTarget(rsc, NULL, slot);
|
||||
}
|
||||
|
||||
static void SC_clearFrameBufferObjectDepthTarget() {
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.bindDepthTarget(rsc, NULL);
|
||||
}
|
||||
|
||||
static void SC_clearFrameBufferObjectTargets() {
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.resetAll(rsc);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// VP
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -275,6 +302,10 @@ static void SC_color(float r, float g, float b, float a) {
|
||||
pf->setConstantColor(rsc, r, g, b, a);
|
||||
}
|
||||
|
||||
static void SC_finish() {
|
||||
glFinish();
|
||||
}
|
||||
|
||||
static void SC_allocationSyncAll(RsAllocation va) {
|
||||
CHECK_OBJ(va);
|
||||
GET_TLS();
|
||||
@ -291,6 +322,7 @@ static void SC_allocationSyncAll2(RsAllocation va, RsAllocationUsageType source)
|
||||
|
||||
static void SC_ClearColor(float r, float g, float b, float a) {
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.setupGL2(rsc);
|
||||
rsc->setupProgramStore();
|
||||
|
||||
glClearColor(r, g, b, a);
|
||||
@ -299,6 +331,7 @@ static void SC_ClearColor(float r, float g, float b, float a) {
|
||||
|
||||
static void SC_ClearDepth(float v) {
|
||||
GET_TLS();
|
||||
rsc->mFBOCache.setupGL2(rsc);
|
||||
rsc->setupProgramStore();
|
||||
|
||||
glClearDepthf(v);
|
||||
@ -444,8 +477,15 @@ static ScriptCState::SymbolTable_t gSyms[] = {
|
||||
{ "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
|
||||
{ "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
|
||||
|
||||
{ "_Z18rsgBindColorTarget13rs_allocationj", (void *)&SC_bindFrameBufferObjectColorTarget, false },
|
||||
{ "_Z18rsgBindDepthTarget13rs_allocation", (void *)&SC_bindFrameBufferObjectDepthTarget, false },
|
||||
{ "_Z19rsgClearColorTargetj", (void *)&SC_clearFrameBufferObjectColorTarget, false },
|
||||
{ "_Z19rsgClearDepthTargetv", (void *)&SC_clearFrameBufferObjectDepthTarget, false },
|
||||
{ "_Z24rsgClearAllRenderTargetsv", (void *)&SC_clearFrameBufferObjectTargets, false },
|
||||
|
||||
// misc
|
||||
{ "_Z5colorffff", (void *)&SC_color, false },
|
||||
{ "_Z9rsgFinishv", (void *)&SC_finish, false },
|
||||
|
||||
{ NULL, NULL, false }
|
||||
};
|
||||
|
@ -1,6 +1,46 @@
|
||||
#ifndef __RS_GRAPHICS_RSH__
|
||||
#define __RS_GRAPHICS_RSH__
|
||||
|
||||
/**
|
||||
* Set the color target used for all subsequent rendering calls
|
||||
* @param colorTarget
|
||||
* @param slot
|
||||
*/
|
||||
extern void __attribute__((overloadable))
|
||||
rsgBindColorTarget(rs_allocation colorTarget, uint slot);
|
||||
|
||||
/**
|
||||
* Clear the previously set color target
|
||||
* @param slot
|
||||
*/
|
||||
extern void __attribute__((overloadable))
|
||||
rsgClearColorTarget(uint slot);
|
||||
|
||||
/**
|
||||
* Set the depth target used for all subsequent rendering calls
|
||||
* @param depthTarget
|
||||
*/
|
||||
extern void __attribute__((overloadable))
|
||||
rsgBindDepthTarget(rs_allocation depthTarget);
|
||||
|
||||
/**
|
||||
* Clear the previously set depth target
|
||||
*/
|
||||
extern void __attribute__((overloadable))
|
||||
rsgClearDepthTarget(void);
|
||||
|
||||
/**
|
||||
* Clear all color and depth targets and resume rendering into
|
||||
* the framebuffer
|
||||
*/
|
||||
extern void __attribute__((overloadable))
|
||||
rsgClearAllRenderTargets(void);
|
||||
|
||||
/**
|
||||
* Force RenderScript to finish all rendering commands
|
||||
*/
|
||||
extern uint __attribute__((overloadable))
|
||||
rsgFinish(void);
|
||||
|
||||
/**
|
||||
* Bind a new ProgramFragment to the rendering context.
|
||||
|
30
tests/RenderScriptTests/FBOTest/Android.mk
Normal file
30
tests/RenderScriptTests/FBOTest/Android.mk
Normal file
@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright (C) 2008 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.
|
||||
#
|
||||
|
||||
ifneq ($(TARGET_SIMULATOR),true)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := FBOTest
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
endif
|
13
tests/RenderScriptTests/FBOTest/AndroidManifest.xml
Normal file
13
tests/RenderScriptTests/FBOTest/AndroidManifest.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.fbotest">
|
||||
<application android:label="_FBOTest">
|
||||
<activity android:name="FBOTest"
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
BIN
tests/RenderScriptTests/FBOTest/res/drawable/robot.png
Normal file
BIN
tests/RenderScriptTests/FBOTest/res/drawable/robot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 286 KiB |
BIN
tests/RenderScriptTests/FBOTest/res/raw/robot.a3d
Normal file
BIN
tests/RenderScriptTests/FBOTest/res/raw/robot.a3d
Normal file
Binary file not shown.
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
package com.android.fbotest;
|
||||
|
||||
import android.renderscript.RSSurfaceView;
|
||||
import android.renderscript.RenderScript;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.provider.Settings.System;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.lang.Runtime;
|
||||
|
||||
public class FBOTest extends Activity {
|
||||
|
||||
private FBOTestView mView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
// Create our Preview view and set it as the content of our
|
||||
// Activity
|
||||
mView = new FBOTestView(this);
|
||||
setContentView(mView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
mView.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
mView.pause();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.fbotest;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Element.DataType;
|
||||
import android.renderscript.Element.DataKind;
|
||||
import android.renderscript.ProgramStore.DepthFunc;
|
||||
import android.renderscript.Type.Builder;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
public class FBOTestRS {
|
||||
|
||||
public FBOTestRS() {
|
||||
}
|
||||
|
||||
public void init(RenderScriptGL rs, Resources res) {
|
||||
mRS = rs;
|
||||
mRes = res;
|
||||
initRS();
|
||||
}
|
||||
|
||||
public void surfaceChanged() {
|
||||
mRS.getWidth();
|
||||
mRS.getHeight();
|
||||
}
|
||||
|
||||
private Resources mRes;
|
||||
private RenderScriptGL mRS;
|
||||
private Sampler mSampler;
|
||||
private ProgramStore mPSBackground;
|
||||
private ProgramFragment mPFBackground;
|
||||
private ProgramVertex mPVBackground;
|
||||
private ProgramVertexFixedFunction.Constants mPVA;
|
||||
|
||||
private Allocation mGridImage;
|
||||
private Allocation mOffscreen;
|
||||
private Allocation mOffscreenDepth;
|
||||
private Allocation mAllocPV;
|
||||
|
||||
private Font mItalic;
|
||||
private Allocation mTextAlloc;
|
||||
|
||||
private ScriptField_MeshInfo mMeshes;
|
||||
private ScriptC_fbotest mScript;
|
||||
|
||||
|
||||
public void onActionDown(float x, float y) {
|
||||
mScript.invoke_onActionDown(x, y);
|
||||
}
|
||||
|
||||
public void onActionScale(float scale) {
|
||||
mScript.invoke_onActionScale(scale);
|
||||
}
|
||||
|
||||
public void onActionMove(float x, float y) {
|
||||
mScript.invoke_onActionMove(x, y);
|
||||
}
|
||||
|
||||
private void initPFS() {
|
||||
ProgramStore.Builder b = new ProgramStore.Builder(mRS);
|
||||
|
||||
b.setDepthFunc(ProgramStore.DepthFunc.LESS);
|
||||
b.setDitherEnabled(false);
|
||||
b.setDepthMaskEnabled(true);
|
||||
mPSBackground = b.create();
|
||||
|
||||
mScript.set_gPFSBackground(mPSBackground);
|
||||
}
|
||||
|
||||
private void initPF() {
|
||||
Sampler.Builder bs = new Sampler.Builder(mRS);
|
||||
bs.setMinification(Sampler.Value.LINEAR);
|
||||
bs.setMagnification(Sampler.Value.LINEAR);
|
||||
bs.setWrapS(Sampler.Value.CLAMP);
|
||||
bs.setWrapT(Sampler.Value.CLAMP);
|
||||
mSampler = bs.create();
|
||||
|
||||
ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
|
||||
b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
|
||||
ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
|
||||
mPFBackground = b.create();
|
||||
mPFBackground.bindSampler(mSampler, 0);
|
||||
|
||||
mScript.set_gPFBackground(mPFBackground);
|
||||
}
|
||||
|
||||
private void initPV() {
|
||||
ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
|
||||
mPVBackground = pvb.create();
|
||||
|
||||
mPVA = new ProgramVertexFixedFunction.Constants(mRS);
|
||||
((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
|
||||
|
||||
mScript.set_gPVBackground(mPVBackground);
|
||||
}
|
||||
|
||||
private void loadImage() {
|
||||
mGridImage = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
|
||||
Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE);
|
||||
mScript.set_gTGrid(mGridImage);
|
||||
}
|
||||
|
||||
private void initTextAllocation(String fileName) {
|
||||
String allocString = "Displaying file: " + fileName;
|
||||
mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT);
|
||||
mScript.set_gTextAlloc(mTextAlloc);
|
||||
}
|
||||
|
||||
private void initMeshes(FileA3D model) {
|
||||
int numEntries = model.getIndexEntryCount();
|
||||
int numMeshes = 0;
|
||||
for (int i = 0; i < numEntries; i ++) {
|
||||
FileA3D.IndexEntry entry = model.getIndexEntry(i);
|
||||
if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
|
||||
numMeshes ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numMeshes > 0) {
|
||||
mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
|
||||
|
||||
for (int i = 0; i < numEntries; i ++) {
|
||||
FileA3D.IndexEntry entry = model.getIndexEntry(i);
|
||||
if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
|
||||
Mesh mesh = entry.getMesh();
|
||||
mMeshes.set_mMesh(i, mesh, false);
|
||||
mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
|
||||
}
|
||||
}
|
||||
mMeshes.copyAll();
|
||||
} else {
|
||||
throw new RSRuntimeException("No valid meshes in file");
|
||||
}
|
||||
|
||||
mScript.bind_gMeshes(mMeshes);
|
||||
mScript.invoke_updateMeshInfo();
|
||||
}
|
||||
|
||||
public void loadA3DFile(String path) {
|
||||
FileA3D model = FileA3D.createFromFile(mRS, path);
|
||||
initMeshes(model);
|
||||
initTextAllocation(path);
|
||||
}
|
||||
|
||||
private void initRS() {
|
||||
|
||||
mScript = new ScriptC_fbotest(mRS, mRes, R.raw.fbotest);
|
||||
|
||||
initPFS();
|
||||
initPF();
|
||||
initPV();
|
||||
|
||||
loadImage();
|
||||
|
||||
Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
|
||||
b.setX(512).setY(512);
|
||||
mOffscreen = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE |
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mScript.set_gOffscreen(mOffscreen);
|
||||
|
||||
b = new Type.Builder(mRS,
|
||||
Element.createPixel(mRS, DataType.UNSIGNED_16,
|
||||
DataKind.PIXEL_DEPTH));
|
||||
b.setX(512).setY(512);
|
||||
mOffscreenDepth = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mScript.set_gOffscreenDepth(mOffscreenDepth);
|
||||
|
||||
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
|
||||
initMeshes(model);
|
||||
|
||||
mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
|
||||
mScript.set_gItalic(mItalic);
|
||||
|
||||
initTextAllocation("R.raw.robot");
|
||||
|
||||
mRS.bindRootScript(mScript);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.fbotest;
|
||||
|
||||
import android.renderscript.RSSurfaceView;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.util.Log;
|
||||
|
||||
public class FBOTestView extends RSSurfaceView {
|
||||
|
||||
private RenderScriptGL mRS;
|
||||
private FBOTestRS mRender;
|
||||
|
||||
private ScaleGestureDetector mScaleDetector;
|
||||
|
||||
private static final int INVALID_POINTER_ID = -1;
|
||||
private int mActivePointerId = INVALID_POINTER_ID;
|
||||
|
||||
public FBOTestView(Context context) {
|
||||
super(context);
|
||||
ensureRenderScript();
|
||||
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
|
||||
}
|
||||
|
||||
private void ensureRenderScript() {
|
||||
if (mRS == null) {
|
||||
RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
|
||||
sc.setDepth(16, 24);
|
||||
mRS = createRenderScriptGL(sc);
|
||||
mRender = new FBOTestRS();
|
||||
mRender.init(mRS, getResources());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
ensureRenderScript();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
super.surfaceChanged(holder, format, w, h);
|
||||
mRender.surfaceChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
mRender = null;
|
||||
if (mRS != null) {
|
||||
mRS = null;
|
||||
destroyRenderScriptGL();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadA3DFile(String path) {
|
||||
mRender.loadA3DFile(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
mScaleDetector.onTouchEvent(ev);
|
||||
|
||||
boolean ret = false;
|
||||
float x = ev.getX();
|
||||
float y = ev.getY();
|
||||
|
||||
final int action = ev.getAction();
|
||||
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mRender.onActionDown(x, y);
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (!mScaleDetector.isInProgress()) {
|
||||
mRender.onActionMove(x, y);
|
||||
}
|
||||
mRender.onActionDown(x, y);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP: {
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
final int pointerId = ev.getPointerId(pointerIndex);
|
||||
if (pointerId == mActivePointerId) {
|
||||
// This was our active pointer going up. Choose a new
|
||||
// active pointer and adjust accordingly.
|
||||
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
|
||||
x = ev.getX(newPointerIndex);
|
||||
y = ev.getY(newPointerIndex);
|
||||
mRender.onActionDown(x, y);
|
||||
mActivePointerId = ev.getPointerId(newPointerIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
mRender.onActionScale(detector.getScaleFactor());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,221 @@
|
||||
// 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.
|
||||
|
||||
#pragma version(1)
|
||||
|
||||
#pragma rs java_package_name(com.android.fbotest)
|
||||
|
||||
#include "rs_graphics.rsh"
|
||||
|
||||
rs_program_vertex gPVBackground;
|
||||
rs_program_fragment gPFBackground;
|
||||
|
||||
rs_allocation gTGrid;
|
||||
|
||||
rs_program_store gPFSBackground;
|
||||
|
||||
rs_font gItalic;
|
||||
rs_allocation gTextAlloc;
|
||||
|
||||
rs_allocation gOffscreen;
|
||||
rs_allocation gOffscreenDepth;
|
||||
|
||||
typedef struct MeshInfo {
|
||||
rs_mesh mMesh;
|
||||
int mNumIndexSets;
|
||||
float3 bBoxMin;
|
||||
float3 bBoxMax;
|
||||
} MeshInfo_t;
|
||||
|
||||
MeshInfo_t *gMeshes;
|
||||
|
||||
static float3 gLookAt;
|
||||
|
||||
static float gRotateX;
|
||||
static float gRotateY;
|
||||
static float gZoom;
|
||||
|
||||
static float gLastX;
|
||||
static float gLastY;
|
||||
|
||||
void onActionDown(float x, float y) {
|
||||
gLastX = x;
|
||||
gLastY = y;
|
||||
}
|
||||
|
||||
void onActionScale(float scale) {
|
||||
|
||||
gZoom *= 1.0f / scale;
|
||||
gZoom = max(0.1f, min(gZoom, 500.0f));
|
||||
}
|
||||
|
||||
void onActionMove(float x, float y) {
|
||||
float dx = gLastX - x;
|
||||
float dy = gLastY - y;
|
||||
|
||||
if (fabs(dy) <= 2.0f) {
|
||||
dy = 0.0f;
|
||||
}
|
||||
if (fabs(dx) <= 2.0f) {
|
||||
dx = 0.0f;
|
||||
}
|
||||
|
||||
gRotateY -= dx;
|
||||
if (gRotateY > 360) {
|
||||
gRotateY -= 360;
|
||||
}
|
||||
if (gRotateY < 0) {
|
||||
gRotateY += 360;
|
||||
}
|
||||
|
||||
gRotateX -= dy;
|
||||
gRotateX = min(gRotateX, 80.0f);
|
||||
gRotateX = max(gRotateX, -80.0f);
|
||||
|
||||
gLastX = x;
|
||||
gLastY = y;
|
||||
}
|
||||
|
||||
void init() {
|
||||
gRotateX = 0.0f;
|
||||
gRotateY = 0.0f;
|
||||
gZoom = 50.0f;
|
||||
gLookAt = 0.0f;
|
||||
}
|
||||
|
||||
void updateMeshInfo() {
|
||||
rs_allocation allMeshes = rsGetAllocation(gMeshes);
|
||||
int size = rsAllocationGetDimX(allMeshes);
|
||||
gLookAt = 0.0f;
|
||||
float minX, minY, minZ, maxX, maxY, maxZ;
|
||||
for (int i = 0; i < size; i++) {
|
||||
MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
|
||||
rsgMeshComputeBoundingBox(info->mMesh,
|
||||
&minX, &minY, &minZ,
|
||||
&maxX, &maxY, &maxZ);
|
||||
info->bBoxMin = (minX, minY, minZ);
|
||||
info->bBoxMax = (maxX, maxY, maxZ);
|
||||
gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
|
||||
}
|
||||
gLookAt = gLookAt / (float)size;
|
||||
}
|
||||
|
||||
static void renderAllMeshes() {
|
||||
rs_allocation allMeshes = rsGetAllocation(gMeshes);
|
||||
int size = rsAllocationGetDimX(allMeshes);
|
||||
gLookAt = 0.0f;
|
||||
float minX, minY, minZ, maxX, maxY, maxZ;
|
||||
for (int i = 0; i < size; i++) {
|
||||
MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
|
||||
rsgDrawMesh(info->mMesh);
|
||||
}
|
||||
}
|
||||
|
||||
static void drawDescription() {
|
||||
uint width = rsgGetWidth();
|
||||
uint height = rsgGetHeight();
|
||||
int left = 0, right = 0, top = 0, bottom = 0;
|
||||
|
||||
rsgBindFont(gItalic);
|
||||
|
||||
rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
|
||||
rsgDrawText(gTextAlloc, 2 -left, height - 2 + bottom);
|
||||
}
|
||||
|
||||
static void renderOffscreen(bool useDepth) {
|
||||
|
||||
rsgBindColorTarget(gOffscreen, 0);
|
||||
if (useDepth) {
|
||||
rsgBindDepthTarget(gOffscreenDepth);
|
||||
rsgClearDepth(1.0f);
|
||||
} else {
|
||||
rsgClearDepthTarget();
|
||||
}
|
||||
rsgClearColor(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
|
||||
rsgBindProgramVertex(gPVBackground);
|
||||
rs_matrix4x4 proj;
|
||||
float aspect = (float)rsAllocationGetDimX(gOffscreen) / (float)rsAllocationGetDimY(gOffscreen);
|
||||
rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
|
||||
rsgBindProgramFragment(gPFBackground);
|
||||
rsgBindProgramStore(gPFSBackground);
|
||||
rsgBindTexture(gPFBackground, 0, gTGrid);
|
||||
|
||||
rs_matrix4x4 matrix;
|
||||
rsMatrixLoadIdentity(&matrix);
|
||||
// Position our models on the screen
|
||||
rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
|
||||
rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
|
||||
rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
|
||||
rsgProgramVertexLoadModelMatrix(&matrix);
|
||||
|
||||
renderAllMeshes();
|
||||
|
||||
// Render into the frambuffer
|
||||
rsgClearAllRenderTargets();
|
||||
}
|
||||
|
||||
static void drawOffscreenResult(int posX, int posY) {
|
||||
// display the result
|
||||
rs_matrix4x4 proj, matrix;
|
||||
rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
rsMatrixLoadIdentity(&matrix);
|
||||
rsgProgramVertexLoadModelMatrix(&matrix);
|
||||
rsgBindTexture(gPFBackground, 0, gOffscreen);
|
||||
float startX = posX, startY = posY;
|
||||
float width = 256, height = 256;
|
||||
rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
|
||||
startX, startY + height, 0, 0, 0,
|
||||
startX + width, startY + height, 0, 1, 0,
|
||||
startX + width, startY, 0, 1, 1);
|
||||
}
|
||||
|
||||
int root(int launchID) {
|
||||
|
||||
rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
rsgClearDepth(1.0f);
|
||||
|
||||
renderOffscreen(true);
|
||||
drawOffscreenResult(0, 0);
|
||||
|
||||
renderOffscreen(false);
|
||||
drawOffscreenResult(0, 256);
|
||||
|
||||
rsgBindProgramVertex(gPVBackground);
|
||||
rs_matrix4x4 proj;
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
|
||||
rsgBindProgramFragment(gPFBackground);
|
||||
rsgBindProgramStore(gPFSBackground);
|
||||
rsgBindTexture(gPFBackground, 0, gTGrid);
|
||||
|
||||
rs_matrix4x4 matrix;
|
||||
rsMatrixLoadIdentity(&matrix);
|
||||
// Position our models on the screen
|
||||
rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
|
||||
rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
|
||||
rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
|
||||
rsgProgramVertexLoadModelMatrix(&matrix);
|
||||
|
||||
renderAllMeshes();
|
||||
|
||||
drawDescription();
|
||||
|
||||
return 0;
|
||||
}
|
@ -22,6 +22,8 @@ import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Element.DataKind;
|
||||
import android.renderscript.Element.DataType;
|
||||
import android.renderscript.Allocation.MipmapControl;
|
||||
import android.renderscript.Program.TextureType;
|
||||
import android.renderscript.ProgramStore.DepthFunc;
|
||||
@ -399,6 +401,23 @@ public class RsBenchRS {
|
||||
initProgramRaster();
|
||||
initCustomShaders();
|
||||
|
||||
Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
|
||||
b.setX(1280).setY(720);
|
||||
Allocation offscreen = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_TEXTURE |
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mScript.set_gRenderBufferColor(offscreen);
|
||||
|
||||
b = new Type.Builder(mRS,
|
||||
Element.createPixel(mRS, DataType.UNSIGNED_16,
|
||||
DataKind.PIXEL_DEPTH));
|
||||
b.setX(1280).setY(720);
|
||||
offscreen = Allocation.createTyped(mRS,
|
||||
b.create(),
|
||||
Allocation.USAGE_GRAPHICS_RENDER_TARGET);
|
||||
mScript.set_gRenderBufferDepth(offscreen);
|
||||
|
||||
mRS.bindRootScript(mScript);
|
||||
}
|
||||
}
|
||||
|
@ -76,11 +76,17 @@ rs_program_vertex gProgVertexPixelLightMove;
|
||||
rs_program_fragment gProgFragmentPixelLight;
|
||||
rs_program_fragment gProgFragmentMultitex;
|
||||
|
||||
rs_allocation gRenderBufferColor;
|
||||
rs_allocation gRenderBufferDepth;
|
||||
|
||||
float gDt = 0;
|
||||
|
||||
void init() {
|
||||
}
|
||||
|
||||
static int gRenderSurfaceW;
|
||||
static int gRenderSurfaceH;
|
||||
|
||||
static const char *sampleText = "This is a sample of small text for performace";
|
||||
// Offsets for multiple layer of text
|
||||
static int textOffsets[] = { 0, 0, -5, -5, 5, 5, -8, -8, 8, 8};
|
||||
@ -91,6 +97,11 @@ static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.6f, 0.7f, 1.0f,
|
||||
};
|
||||
|
||||
static void setupOffscreenTarget() {
|
||||
rsgBindColorTarget(gRenderBufferColor, 0);
|
||||
rsgBindDepthTarget(gRenderBufferDepth);
|
||||
}
|
||||
|
||||
static void displayFontSamples(int fillNum) {
|
||||
|
||||
rs_font fonts[5];
|
||||
@ -100,8 +111,8 @@ static void displayFontSamples(int fillNum) {
|
||||
rsSetObject(&fonts[3], gFontSerifBoldItalic);
|
||||
rsSetObject(&fonts[4], gFontSans);
|
||||
|
||||
uint width = rsgGetWidth();
|
||||
uint height = rsgGetHeight();
|
||||
uint width = gRenderSurfaceW;
|
||||
uint height = gRenderSurfaceH;
|
||||
int left = 0, right = 0, top = 0, bottom = 0;
|
||||
rsgMeasureText(sampleText, &left, &right, &top, &bottom);
|
||||
|
||||
@ -136,7 +147,7 @@ static void bindProgramVertexOrtho() {
|
||||
rsgBindProgramVertex(gProgVertex);
|
||||
// Setup the projection matrix
|
||||
rs_matrix4x4 proj;
|
||||
rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
|
||||
rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
}
|
||||
|
||||
@ -158,7 +169,7 @@ static void displaySingletexFill(bool blend, int quadCount) {
|
||||
|
||||
for (int i = 0; i < quadCount; i ++) {
|
||||
float startX = 10 * i, startY = 10 * i;
|
||||
float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY;
|
||||
float width = gRenderSurfaceW - startX, height = gRenderSurfaceH - startY;
|
||||
rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
|
||||
startX, startY + height, 0, 0, 1,
|
||||
startX + width, startY + height, 0, 1, 1,
|
||||
@ -216,7 +227,7 @@ static void displayMeshSamples(int meshNum) {
|
||||
|
||||
bindProgramVertexOrtho();
|
||||
rs_matrix4x4 matrix;
|
||||
rsMatrixLoadTranslate(&matrix, rsgGetWidth()/2, rsgGetHeight()/2, 0);
|
||||
rsMatrixLoadTranslate(&matrix, gRenderSurfaceW/2, gRenderSurfaceH/2, 0);
|
||||
rsgProgramVertexLoadModelMatrix(&matrix);
|
||||
|
||||
// Fragment shader with texture
|
||||
@ -344,7 +355,7 @@ static void displaySimpleGeoSamples(bool useTexture, int numMeshes) {
|
||||
rsgBindProgramRaster(gCullBack);
|
||||
// Setup the projection matrix with 30 degree field of view
|
||||
rs_matrix4x4 proj;
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH;
|
||||
rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
|
||||
@ -445,7 +456,7 @@ static void displayCustomShaderSamples(int numMeshes) {
|
||||
}
|
||||
|
||||
// Setup the projection matrix
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH;
|
||||
rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
|
||||
setupCustomShaderLights();
|
||||
|
||||
@ -476,7 +487,7 @@ static void displayPixelLightSamples(int numMeshes, bool heavyVertex) {
|
||||
gVSConstPixel->time = rsUptimeMillis()*0.005;
|
||||
|
||||
// Setup the projection matrix
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH;
|
||||
rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f);
|
||||
setupCustomShaderLights();
|
||||
|
||||
@ -520,7 +531,7 @@ static void displayMultitextureSample(bool blend, int quadCount) {
|
||||
|
||||
for (int i = 0; i < quadCount; i ++) {
|
||||
float startX = 10 * i, startY = 10 * i;
|
||||
float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY;
|
||||
float width = gRenderSurfaceW - startX, height = gRenderSurfaceH - startY;
|
||||
rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
|
||||
startX, startY + height, 0, 0, 1,
|
||||
startX + width, startY + height, 0, 1, 1,
|
||||
@ -535,7 +546,7 @@ static void displayAnisoSample() {
|
||||
gAnisoTime += gDt;
|
||||
|
||||
rsgBindProgramVertex(gProgVertex);
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
float aspect = (float)gRenderSurfaceW / (float)gRenderSurfaceH;
|
||||
rs_matrix4x4 proj;
|
||||
rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
|
||||
rsgProgramVertexLoadProjectionMatrix(&proj);
|
||||
@ -592,10 +603,6 @@ static bool checkInit() {
|
||||
|
||||
static int countdown = 5;
|
||||
|
||||
if (countdown == 0) {
|
||||
gDt = 0;
|
||||
countdown --;
|
||||
}
|
||||
// Perform all the uploads so we only measure rendered time
|
||||
if(countdown > 1) {
|
||||
displayFontSamples(5);
|
||||
@ -612,19 +619,13 @@ static bool checkInit() {
|
||||
countdown --;
|
||||
rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
|
||||
|
||||
// Now use text metrics to center the text
|
||||
uint width = rsgGetWidth();
|
||||
uint height = rsgGetHeight();
|
||||
int left = 0, right = 0, top = 0, bottom = 0;
|
||||
|
||||
rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
|
||||
rsgBindFont(gFontSerifBoldItalic);
|
||||
|
||||
const char* text = "Initializing";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
int centeredPosX = width / 2 - (right - left) / 2;
|
||||
int centeredPosY = height / 2 - (top - bottom) / 2;
|
||||
rsgDrawText(text, centeredPosX, centeredPosY);
|
||||
if (countdown == 1) {
|
||||
rsgDrawText("Rendering", 50, 50);
|
||||
} else {
|
||||
rsgDrawText("Initializing", 50, 50);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -632,70 +633,40 @@ static bool checkInit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int frameCount = 0;
|
||||
static int totalFramesRendered = 0;
|
||||
static int benchMode = 0;
|
||||
|
||||
#define testTime 5.0f
|
||||
static float curTestTime = testTime;
|
||||
|
||||
static const char *testNames[] = {
|
||||
"Finished text fill 1",
|
||||
"Finished text fill 2",
|
||||
"Finished text fill 3",
|
||||
"Finished text fill 4",
|
||||
"Finished text fill 5",
|
||||
"Finished 25.6k geo flat color",
|
||||
"Finished 51.2k geo flat color",
|
||||
"Finished 204.8k geo raster load flat color",
|
||||
"Finished 25.6k geo texture",
|
||||
"Finished 51.2k geo texture",
|
||||
"Finished 204.8k geo raster load texture",
|
||||
"Finished full screen mesh 10 by 10",
|
||||
"Finished full screen mesh 100 by 100",
|
||||
"Finished full screen mesh W / 4 by H / 4",
|
||||
"Finished 25.6k geo heavy vertex",
|
||||
"Finished 51.2k geo heavy vertex",
|
||||
"Finished 204.8k geo raster load heavy vertex",
|
||||
"Finished singletexture 5x fill",
|
||||
"Finished 3tex multitexture 5x fill",
|
||||
"Finished blend singletexture 5x fill",
|
||||
"Finished blend 3tex multitexture 5x fill",
|
||||
"Finished 25.6k geo heavy fragment",
|
||||
"Finished 51.2k geo heavy fragment",
|
||||
"Finished 204.8k geo raster load heavy fragment",
|
||||
"Finished 25.6k geo heavy fragment, heavy vertex",
|
||||
"Finished 51.2k geo heavy fragment, heavy vertex",
|
||||
"Finished 204.8k geo raster load heavy fragment, heavy vertex",
|
||||
"Finished text fill 1,",
|
||||
"Finished text fill 2,",
|
||||
"Finished text fill 3,",
|
||||
"Finished text fill 4,",
|
||||
"Finished text fill 5,",
|
||||
"Finished 25.6k geo flat color,",
|
||||
"Finished 51.2k geo flat color,",
|
||||
"Finished 204.8k geo raster load flat color,",
|
||||
"Finished 25.6k geo texture,",
|
||||
"Finished 51.2k geo texture,",
|
||||
"Finished 204.8k geo raster load texture,",
|
||||
"Finished full screen mesh 10 by 10,",
|
||||
"Finished full screen mesh 100 by 100,",
|
||||
"Finished full screen mesh W / 4 by H / 4,",
|
||||
"Finished 25.6k geo heavy vertex,",
|
||||
"Finished 51.2k geo heavy vertex,",
|
||||
"Finished 204.8k geo raster load heavy vertex,",
|
||||
"Finished singletexture 5x fill,",
|
||||
"Finished 3tex multitexture 5x fill,",
|
||||
"Finished blend singletexture 5x fill,",
|
||||
"Finished blend 3tex multitexture 5x fill,",
|
||||
"Finished 25.6k geo heavy fragment,",
|
||||
"Finished 51.2k geo heavy fragment,",
|
||||
"Finished 204.8k geo raster load heavy fragment,",
|
||||
"Finished 25.6k geo heavy fragment heavy vertex,",
|
||||
"Finished 51.2k geo heavy fragment heavy vertex,",
|
||||
"Finished 204.8k geo raster load heavy fragment heavy vertex,",
|
||||
};
|
||||
|
||||
int root(int launchID) {
|
||||
|
||||
gDt = rsGetDt();
|
||||
|
||||
rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
|
||||
rsgClearDepth(1.0f);
|
||||
|
||||
if(!checkInit()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
curTestTime -= gDt;
|
||||
if(curTestTime < 0.0f) {
|
||||
float fps = (float)(frameCount) / (testTime - curTestTime);
|
||||
rsDebug(testNames[benchMode], fps);
|
||||
benchMode ++;
|
||||
curTestTime = testTime;
|
||||
totalFramesRendered += frameCount;
|
||||
frameCount = 0;
|
||||
gTorusRotation = 0;
|
||||
|
||||
if (benchMode > gMaxModes) {
|
||||
benchMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (benchMode) {
|
||||
static void runTest(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
displayFontSamples(1);
|
||||
break;
|
||||
@ -777,10 +748,87 @@ int root(int launchID) {
|
||||
case 26:
|
||||
displayPixelLightSamples(8, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void drawOffscreenResult(int posX, int posY, int width, int height) {
|
||||
bindProgramVertexOrtho();
|
||||
|
||||
rs_matrix4x4 matrix;
|
||||
rsMatrixLoadIdentity(&matrix);
|
||||
rsgProgramVertexLoadModelMatrix(&matrix);
|
||||
|
||||
rsgBindProgramFragment(gProgFragmentTexture);
|
||||
|
||||
rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
|
||||
rsgBindTexture(gProgFragmentTexture, 0, gRenderBufferColor);
|
||||
|
||||
float startX = posX, startY = posY;
|
||||
rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
|
||||
startX, startY + height, 0, 0, 0,
|
||||
startX + width, startY + height, 0, 1, 0,
|
||||
startX + width, startY, 0, 1, 1);
|
||||
}
|
||||
|
||||
int root(int launchID) {
|
||||
|
||||
gRenderSurfaceW = rsgGetWidth();
|
||||
gRenderSurfaceH = rsgGetHeight();
|
||||
rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
rsgClearDepth(1.0f);
|
||||
if(!checkInit()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
frameCount ++;
|
||||
rsgFinish();
|
||||
int64_t start = rsUptimeMillis();
|
||||
rsGetDt();
|
||||
|
||||
int drawPos = 0;
|
||||
int frameCount = 100;
|
||||
for(int i = 0; i < frameCount; i ++) {
|
||||
setupOffscreenTarget();
|
||||
gRenderSurfaceW = rsAllocationGetDimX(gRenderBufferColor);
|
||||
gRenderSurfaceH = rsAllocationGetDimY(gRenderBufferColor);
|
||||
rsgClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
rsgClearDepth(1.0f);
|
||||
|
||||
runTest(benchMode);
|
||||
rsgClearAllRenderTargets();
|
||||
gRenderSurfaceW = rsgGetWidth();
|
||||
gRenderSurfaceH = rsgGetHeight();
|
||||
int size = 8;
|
||||
drawOffscreenResult((drawPos+=size)%gRenderSurfaceW, (gRenderSurfaceH * 3) / 4, size, size);
|
||||
gDt = rsGetDt();
|
||||
}
|
||||
|
||||
rsgFinish();
|
||||
|
||||
int64_t end = rsUptimeMillis();
|
||||
float fps = (float)(frameCount) / ((float)(end - start)*0.001f);
|
||||
rsDebug(testNames[benchMode], fps);
|
||||
|
||||
drawOffscreenResult(0, 0,
|
||||
gRenderSurfaceW / 2,
|
||||
gRenderSurfaceH / 2);
|
||||
|
||||
const char* text = testNames[benchMode];
|
||||
int left = 0, right = 0, top = 0, bottom = 0;
|
||||
uint width = rsgGetWidth();
|
||||
uint height = rsgGetHeight();
|
||||
rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
|
||||
rsgBindFont(gFontSerifBoldItalic);
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
rsgDrawText(text, 2 -left, height - 2 + bottom);
|
||||
|
||||
benchMode ++;
|
||||
|
||||
gTorusRotation = 0;
|
||||
|
||||
if (benchMode > gMaxModes) {
|
||||
benchMode = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user