diff options
Diffstat (limited to 'libs')
46 files changed, 2141 insertions, 568 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index 13c58f0..95cfddf 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -318,6 +318,16 @@ restart: goto restart; } +IPCThreadState* IPCThreadState::selfOrNull() +{ + if (gHaveTLS) { + const pthread_key_t k = gTLS; + IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); + return st; + } + return NULL; +} + void IPCThreadState::shutdown() { gShutdown = true; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index b357973..72c8950 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -268,7 +268,7 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, const GLuint previousFbo = mSnapshot->fbo; const int count = saveSnapshot(flags); - if (!mSnapshot->invisible) { + if (!mSnapshot->isIgnored()) { int alpha = 255; SkXfermode::Mode mode; @@ -385,13 +385,13 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize || bounds.getHeight() > mCaches.maxTextureSize) { - snapshot->invisible = true; + snapshot->empty = fboLayer; } else { snapshot->invisible = snapshot->invisible || (alpha <= ALPHA_THRESHOLD && fboLayer); } // Bail out if we won't draw in this snapshot - if (snapshot->invisible) { + if (snapshot->invisible || snapshot->empty) { return false; } @@ -723,15 +723,8 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top, #endif } -void OpenGLRenderer::setupDraw() { - clearLayerRegions(); - if (mDirtyClip) { - setScissorFromClip(); - } -} - void OpenGLRenderer::clearLayerRegions() { - if (mLayers.size() == 0 || mSnapshot->invisible) return; + if (mLayers.size() == 0 || mSnapshot->isIgnored()) return; Rect clipRect(*mSnapshot->clipRect); clipRect.snapToPixelBoundaries(); @@ -809,7 +802,7 @@ const Rect& OpenGLRenderer::getClipBounds() { } bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { - if (mSnapshot->invisible) { + if (mSnapshot->isIgnored()) { return true; } @@ -832,6 +825,162 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, } /////////////////////////////////////////////////////////////////////////////// +// Drawing commands +/////////////////////////////////////////////////////////////////////////////// + +void OpenGLRenderer::setupDraw() { + clearLayerRegions(); + if (mDirtyClip) { + setScissorFromClip(); + } + mDescription.reset(); + mSetShaderColor = false; + mColorSet = false; + mColorA = mColorR = mColorG = mColorB = 0.0f; + mTextureUnit = 0; + mTrackDirtyRegions = true; +} + +void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) { + mDescription.hasTexture = true; + mDescription.hasAlpha8Texture = isAlpha8; +} + +void OpenGLRenderer::setupDrawColor(int color) { + mColorA = ((color >> 24) & 0xFF) / 255.0f; + const float a = mColorA / 255.0f; + mColorR = a * ((color >> 16) & 0xFF); + mColorG = a * ((color >> 8) & 0xFF); + mColorB = a * ((color ) & 0xFF); + mColorSet = true; + mSetShaderColor = mDescription.setColor(mColorR, mColorG, mColorB, mColorA); +} + +void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) { + mColorA = a; + mColorR = r; + mColorG = g; + mColorB = b; + mColorSet = true; + mSetShaderColor = mDescription.setColor(r, g, b, a); +} + +void OpenGLRenderer::setupDrawShader() { + if (mShader) { + mShader->describe(mDescription, mCaches.extensions); + } +} + +void OpenGLRenderer::setupDrawColorFilter() { + if (mColorFilter) { + mColorFilter->describe(mDescription, mCaches.extensions); + } +} + +void OpenGLRenderer::setupDrawBlending(SkXfermode::Mode mode, bool swapSrcDst) { + chooseBlending((mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode, + mDescription, swapSrcDst); +} + +void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool swapSrcDst) { + chooseBlending(blend || (mColorSet && mColorA < 1.0f) || (mShader && mShader->blend()), mode, + mDescription, swapSrcDst); +} + +void OpenGLRenderer::setupDrawProgram() { + useProgram(mCaches.programCache.get(mDescription)); +} + +void OpenGLRenderer::setupDrawDirtyRegionsDisabled() { + mTrackDirtyRegions = false; +} + +void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float right, float bottom, + bool ignoreTransform) { + mModelView.loadTranslate(left, top, 0.0f); + if (!ignoreTransform) { + mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); + if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *mSnapshot->transform); + } else { + mCaches.currentProgram->set(mOrthoMatrix, mModelView, mIdentity); + if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom); + } +} + +void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom, + bool ignoreTransform, bool ignoreModelView) { + if (!ignoreModelView) { + mModelView.loadTranslate(left, top, 0.0f); + mModelView.scale(right - left, bottom - top, 1.0f); + if (!ignoreTransform) { + mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); + if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *mSnapshot->transform); + } else { + mCaches.currentProgram->set(mOrthoMatrix, mModelView, mIdentity); + if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom); + } + } else { + mModelView.loadIdentity(); + } +} + +void OpenGLRenderer::setupDrawColorUniforms() { + if (mColorSet || (mShader && mSetShaderColor)) { + mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA); + } +} + +void OpenGLRenderer::setupDrawColorAlphaUniforms() { + if (mSetShaderColor) { + mCaches.currentProgram->setColor(mColorA, mColorA, mColorA, mColorA); + } +} + +void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) { + if (mShader) { + if (ignoreTransform) { + mModelView.loadInverse(*mSnapshot->transform); + } + mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &mTextureUnit); + } +} + +void OpenGLRenderer::setupDrawColorFilterUniforms() { + if (mColorFilter) { + mColorFilter->setupProgram(mCaches.currentProgram); + } +} + +void OpenGLRenderer::setupDrawSimpleMesh() { + mCaches.bindMeshBuffer(); + glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, + gMeshStride, 0); +} + +void OpenGLRenderer::setupDrawTexture(GLuint texture) { + bindTexture(texture); + glUniform1i(mCaches.currentProgram->getUniform("sampler"), mTextureUnit++); + + mTexCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); + glEnableVertexAttribArray(mTexCoordsSlot); +} + +void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) { + if (!vertices) { + mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo); + } else { + mCaches.unbindMeshBuffer(); + } + glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, + gMeshStride, vertices); + glVertexAttribPointer(mTexCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords); +} + +void OpenGLRenderer::finishDrawTexture() { + glDisableVertexAttribArray(mTexCoordsSlot); +} + +/////////////////////////////////////////////////////////////////////////////// // Drawing /////////////////////////////////////////////////////////////////////////////// @@ -988,7 +1137,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { // TODO: Should do quickReject for each line - if (mSnapshot->invisible) return; + if (mSnapshot->isIgnored()) return; const bool isAA = paint->isAntiAlias(); const float strokeWidth = paint->getStrokeWidth() * 0.5f; @@ -1043,18 +1192,16 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, gMeshStride, vertex); - mModelView.loadIdentity(); - // Build and use the appropriate shader useProgram(mCaches.programCache.get(description)); - mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); + mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform); if (!mShader || (mShader && setColor)) { mCaches.currentProgram->setColor(r, g, b, a); } if (mShader) { - mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit); + mShader->setupProgram(mCaches.currentProgram, mIdentity, *mSnapshot, &textureUnit); } if (mColorFilter) { mColorFilter->setupProgram(mCaches.currentProgram); @@ -1112,10 +1259,11 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { // No need to check against the clip, we fill the clip region - if (mSnapshot->invisible) return; + if (mSnapshot->isIgnored()) return; Rect& clip(*mSnapshot->clipRect); clip.snapToPixelBoundaries(); + drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true); } @@ -1150,7 +1298,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { return; } - if (mSnapshot->invisible) return; + if (mSnapshot->isIgnored()) return; paint->setAntiAlias(true); @@ -1253,7 +1401,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { - if (mSnapshot->invisible) return; + if (mSnapshot->isIgnored()) return; GLuint textureUnit = 0; glActiveTexture(gTextureUnits[textureUnit]); @@ -1512,84 +1660,26 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color, SkXfermode::Mode mode, bool ignoreTransform) { - setupDraw(); - // If a shader is set, preserve only the alpha if (mShader) { color |= 0x00ffffff; } - // Render using pre-multiplied alpha - const int alpha = (color >> 24) & 0xFF; - const GLfloat a = alpha / 255.0f; - const GLfloat r = a * ((color >> 16) & 0xFF) / 255.0f; - const GLfloat g = a * ((color >> 8) & 0xFF) / 255.0f; - const GLfloat b = a * ((color ) & 0xFF) / 255.0f; - - setupColorRect(left, top, right, bottom, r, g, b, a, mode, ignoreTransform); + setupDraw(); + setupDrawColor(color); + setupDrawShader(); + setupDrawColorFilter(); + setupDrawBlending(mode); + setupDrawProgram(); + setupDrawModelView(left, top, right, bottom, ignoreTransform); + setupDrawColorUniforms(); + setupDrawShaderUniforms(ignoreTransform); + setupDrawColorFilterUniforms(); + setupDrawSimpleMesh(); - // Draw the mesh glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); } -void OpenGLRenderer::setupColorRect(float left, float top, float right, float bottom, - float r, float g, float b, float a, SkXfermode::Mode mode, - bool ignoreTransform, bool ignoreMatrix) { - GLuint textureUnit = 0; - - // Describe the required shaders - ProgramDescription description; - const bool setColor = description.setColor(r, g, b, a); - - if (mShader) { - mShader->describe(description, mCaches.extensions); - } - if (mColorFilter) { - mColorFilter->describe(description, mCaches.extensions); - } - - // Setup the blending mode - chooseBlending(a < 1.0f || (mShader && mShader->blend()), mode, description); - - // Build and use the appropriate shader - useProgram(mCaches.programCache.get(description)); - - // Setup attributes - mCaches.bindMeshBuffer(); - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gMeshStride, 0); - - if (!ignoreMatrix) { - // Setup uniforms - mModelView.loadTranslate(left, top, 0.0f); - mModelView.scale(right - left, bottom - top, 1.0f); - if (!ignoreTransform) { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); - dirtyLayer(left, top, right, bottom, *mSnapshot->transform); - } else { - mat4 identity; - mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity); - dirtyLayer(left, top, right, bottom); - } - } - if (!mShader || (mShader && setColor)) { - mCaches.currentProgram->setColor(r, g, b, a); - } - - // Setup attributes and uniforms required by the shaders - if (mShader) { - if (ignoreMatrix) { - mModelView.loadIdentity(); - } else if (ignoreTransform) { - mModelView.loadInverse(*mSnapshot->transform); - } - mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit); - } - if (mColorFilter) { - mColorFilter->setupProgram(mCaches.currentProgram); - } -} - void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, Texture* texture, SkPaint* paint) { int alpha; @@ -1622,61 +1712,29 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount, bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) { - setupDraw(); - ProgramDescription description; - description.hasTexture = true; - const bool setColor = description.setColor(alpha, alpha, alpha, alpha); - if (mColorFilter) { - mColorFilter->describe(description, mCaches.extensions); + setupDraw(); + setupDrawWithTexture(); + setupDrawColor(alpha, alpha, alpha, alpha); + setupDrawColorFilter(); + setupDrawBlending(blend, mode, swapSrcDst); + setupDrawProgram(); + if (!dirty) { + setupDrawDirtyRegionsDisabled(); } - - mModelView.loadTranslate(left, top, 0.0f); if (!ignoreScale) { - mModelView.scale(right - left, bottom - top, 1.0f); - } - - chooseBlending(blend || alpha < 1.0f, mode, description, swapSrcDst); - - useProgram(mCaches.programCache.get(description)); - if (!ignoreTransform) { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform); - if (dirty) dirtyLayer(left, top, right, bottom, *mSnapshot->transform); - } else { - mat4 identity; - mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity); - if (dirty) dirtyLayer(left, top, right, bottom); - } - - // Texture - bindTexture(texture); - glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0); - - // Always premultiplied - if (setColor) { - mCaches.currentProgram->setColor(alpha, alpha, alpha, alpha); - } - - // Mesh - int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); - glEnableVertexAttribArray(texCoordsSlot); - - if (!vertices) { - mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo); + setupDrawModelView(left, top, right, bottom, ignoreTransform); } else { - mCaches.unbindMeshBuffer(); - } - glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, - gMeshStride, vertices); - glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords); - - // Color filter - if (mColorFilter) { - mColorFilter->setupProgram(mCaches.currentProgram); + setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform); } + setupDrawColorAlphaUniforms(); + setupDrawColorFilterUniforms(); + setupDrawTexture(texture); + setupDrawMesh(vertices, texCoords, vbo); glDrawArrays(drawMode, 0, elementsCount); - glDisableVertexAttribArray(texCoordsSlot); + + finishDrawTexture(); } void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index e866d1b..5d8653d 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -221,13 +221,6 @@ private: int color, SkXfermode::Mode mode, bool ignoreTransform = false); /** - * Setups shaders to draw a colored rect. - */ - void setupColorRect(float left, float top, float right, float bottom, - float r, float g, float b, float a, SkXfermode::Mode mode, - bool ignoreTransform, bool ignoreMatrix = false); - - /** * Draws a textured rectangle with the specified texture. The specified coordinates * are transformed by the current snapshot's transform matrix. * @@ -431,6 +424,32 @@ private: * Invoked before any drawing operation. This sets required state. */ void setupDraw(); + /** + * Various methods to setup OpenGL rendering. + */ + void setupDrawWithTexture(bool isAlpha8 = false); + void setupDrawColor(int color); + void setupDrawColor(float r, float g, float b, float a); + void setupDrawShader(); + void setupDrawColorFilter(); + void setupDrawBlending(SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode, + bool swapSrcDst = false); + void setupDrawBlending(bool blend = true, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode, + bool swapSrcDst = false); + void setupDrawProgram(); + void setupDrawDirtyRegionsDisabled(); + void setupDrawModelView(float left, float top, float right, float bottom, + bool ignoreTransform = false, bool ignoreModelView = false); + void setupDrawModelViewTranslate(float left, float top, float right, float bottom, + bool ignoreTransform = false); + void setupDrawColorUniforms(); + void setupDrawColorAlphaUniforms(); + void setupDrawShaderUniforms(bool ignoreTransform = false); + void setupDrawColorFilterUniforms(); + void setupDrawSimpleMesh(); + void setupDrawTexture(GLuint texture); + void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0); + void finishDrawTexture(); /** * Should be invoked every time the glScissor is modified. @@ -495,6 +514,21 @@ private: // Indicates whether the clip must be restored bool mDirtyClip; + // The following fields are used to setup drawing + // Used to describe the shaders to generate + ProgramDescription mDescription; + // Color description + bool mColorSet; + float mColorA, mColorR, mColorG, mColorB; + // Indicates that the shader should get a color + bool mSetShaderColor; + // Current texture unit + GLuint mTextureUnit; + // Track dirty regions, true by default + bool mTrackDirtyRegions; + // Texture coordinates slot + int mTexCoordsSlot; + friend class DisplayListRenderer; }; // class OpenGLRenderer diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index 951fba3..62d0ce1 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -19,6 +19,7 @@ #include <utils/KeyedVector.h> +#include "utils/Compare.h" #include "Debug.h" #include "Patch.h" diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h index fc3e248..3acd18a 100644 --- a/libs/hwui/ProgramCache.h +++ b/libs/hwui/ProgramCache.h @@ -102,14 +102,8 @@ struct ProgramDescription { kGradientSweep }; - ProgramDescription(): - hasTexture(false), hasAlpha8Texture(false), modulate(false), - hasBitmap(false), isBitmapNpot(false), hasGradient(false), - gradientType(kGradientLinear), - shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false), - bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE), - colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode), - framebufferMode(SkXfermode::kClear_Mode), swapSrcDst(false) { + ProgramDescription() { + reset(); } // Texturing @@ -142,6 +136,35 @@ struct ProgramDescription { bool swapSrcDst; /** + * Resets this description. All fields are reset back to the default + * values they hold after building a new instance. + */ + void reset() { + hasTexture = false; + hasAlpha8Texture = false; + + modulate = false; + + hasBitmap = false; + isBitmapNpot = false; + + hasGradient = false; + gradientType = kGradientLinear; + + shadersMode = SkXfermode::kClear_Mode; + + isBitmapFirst = false; + bitmapWrapS = GL_CLAMP_TO_EDGE; + bitmapWrapT = GL_CLAMP_TO_EDGE; + + colorOp = kColorNone; + colorMode = SkXfermode::kClear_Mode; + + framebufferMode = SkXfermode::kClear_Mode; + swapSrcDst = false; + } + + /** * Indicates, for a given color, whether color modulation is required in * the fragment shader. When this method returns true, the program should * be provided with a modulation color. diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index ac91769..c474936 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -39,7 +39,8 @@ enum DebugLevel { kDebugDisabled = 0, kDebugMemory = 1, - kDebugCaches = 2 + kDebugCaches = 2, + kDebugMoreCaches = 3 }; // These properties are defined in mega-bytes diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index 9f78063..9898df4 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -43,7 +43,7 @@ namespace uirenderer { */ class Snapshot: public LightRefBase<Snapshot> { public: - Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false) { + Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false), empty(false) { transform = &mTransformRoot; clipRect = &mClipRectRoot; region = NULL; @@ -55,7 +55,7 @@ public: */ Snapshot(const sp<Snapshot>& s, int saveFlags): flags(0), previous(s), layer(NULL), fbo(s->fbo), - invisible(s->invisible), viewport(s->viewport), height(s->height) { + invisible(s->invisible), empty(false), viewport(s->viewport), height(s->height) { if (saveFlags & SkCanvas::kMatrix_SaveFlag) { mTransformRoot.load(*s->transform); transform = &mTransformRoot; @@ -203,6 +203,10 @@ public: flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip; } + bool isIgnored() const { + return invisible || empty; + } + /** * Dirty flags. */ @@ -225,11 +229,18 @@ public: /** * Indicates that this snapshot is invisible and nothing should be drawn - * inside it. + * inside it. This flag is set only when the layer clips drawing to its + * bounds and is passed to subsequent snapshots. */ bool invisible; /** + * If set to true, the layer will not be composited. This is similar to + * invisible but this flag is not passed to subsequent snapshots. + */ + bool empty; + + /** * Current viewport. */ Rect viewport; diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index 2f7c7be..d96a7f5 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -37,19 +37,24 @@ TextDropShadowCache::TextDropShadowCache(): LOGD(" Using default drop shadow cache size of %.2fMB", DEFAULT_DROP_SHADOW_CACHE_SIZE); } - mCache.setOnEntryRemovedListener(this); + init(); } TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize): mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { - mCache.setOnEntryRemovedListener(this); + init(); } TextDropShadowCache::~TextDropShadowCache() { mCache.clear(); } +void TextDropShadowCache::init() { + mCache.setOnEntryRemovedListener(this); + mDebugEnabled = readDebugLevel() & kDebugMoreCaches; +} + /////////////////////////////////////////////////////////////////////////////// // Size management /////////////////////////////////////////////////////////////////////////////// @@ -75,8 +80,11 @@ void TextDropShadowCache::setMaxSize(uint32_t maxSize) { void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) { if (texture) { - const uint32_t size = texture->width * texture->height; - mSize -= size; + mSize -= texture->bitmapSize; + + if (mDebugEnabled) { + LOGD("Shadow texture deleted, size = %d", texture->bitmapSize); + } glDeleteTextures(1, &texture->id); delete texture; @@ -109,6 +117,8 @@ ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32 texture->blend = true; const uint32_t size = shadow.width * shadow.height; + texture->bitmapSize = size; + // Don't even try to cache a bitmap that's bigger than the cache if (size < mMaxSize) { while (mSize + size > mMaxSize) { @@ -132,6 +142,9 @@ ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (size < mMaxSize) { + if (mDebugEnabled) { + LOGD("Shadow texture created, size = %d", texture->bitmapSize); + } mSize += size; mCache.put(entry, texture); } else { diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index adf09e2..8cefc8c 100644 --- a/libs/hwui/TextDropShadowCache.h +++ b/libs/hwui/TextDropShadowCache.h @@ -21,6 +21,9 @@ #include <SkPaint.h> +#include <utils/String8.h> + +#include "utils/Compare.h" #include "utils/GenerationCache.h" #include "FontRenderer.h" #include "Texture.h" @@ -29,20 +32,20 @@ namespace android { namespace uirenderer { struct ShadowText { - ShadowText() { - text = NULL; + ShadowText(): radius(0), len(0), hash(0), textSize(0.0f), typeface(NULL) { } ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText): radius(radius), len(len) { - text = new char[len]; - memcpy(text, srcText, len); + // The source text we receive is in UTF-16, convert to UTF-8 + str.setTo((const char16_t*) srcText, len >> 1); textSize = paint->getTextSize(); typeface = paint->getTypeface(); hash = 0; uint32_t multiplier = 1; + const char* text = str.string(); for (uint32_t i = 0; i < len; i++) { hash += text[i] * multiplier; uint32_t shifted = multiplier << 5; @@ -52,13 +55,10 @@ struct ShadowText { ShadowText(const ShadowText& shadow): radius(shadow.radius), len(shadow.len), hash(shadow.hash), - textSize(shadow.textSize), typeface(shadow.typeface) { - text = new char[shadow.len]; - memcpy(text, shadow.text, shadow.len); + textSize(shadow.textSize), typeface(shadow.typeface), str(shadow.str) { } ~ShadowText() { - delete[] text; } uint32_t radius; @@ -66,20 +66,16 @@ struct ShadowText { uint32_t hash; float textSize; SkTypeface* typeface; - char *text; + String8 str; bool operator<(const ShadowText& rhs) const { - if (hash < rhs.hash) return true; - else if (hash == rhs.hash) { - if (len < rhs.len) return true; - else if (len == rhs.len) { - if (radius < rhs.radius) return true; - else if (radius == rhs.radius) { - if (textSize < rhs.textSize) return true; - else if (textSize == rhs.textSize) { + LTE_INT(hash) { + LTE_INT(len) { + LTE_INT(radius) { + LTE_FLOAT(textSize) { if (typeface < rhs.typeface) return true; else if (typeface == rhs.typeface) { - return strncmp(text, rhs.text, len) < 0; + return str.compare(rhs.str) < 0; } } } @@ -138,11 +134,14 @@ public: uint32_t getSize(); private: + void init(); + GenerationCache<ShadowText, ShadowTexture*> mCache; uint32_t mSize; uint32_t mMaxSize; FontRenderer* mRenderer; + bool mDebugEnabled; }; // class TextDropShadowCache }; // namespace uirenderer diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index 9e30799..43d4291 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -105,10 +105,10 @@ enum RsAllocationUsageType { RS_ALLOCATION_USAGE_ALL = 0x000F }; -enum RsAllocationMipmapGenerationControl { - RS_MIPMAP_NONE = 0, - RS_MIPMAP_FULL = 1, - RS_MIPMAP_TEXTURE_ONLY = 2 +enum RsAllocationMipmapControl { + RS_ALLOCATION_MIPMAP_NONE = 0, + RS_ALLOCATION_MIPMAP_FULL = 1, + RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE = 2 }; enum RsDataType { @@ -345,13 +345,13 @@ void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char ** RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimX, uint32_t dimY, uint32_t dimZ, bool mips, bool faces); RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype, - RsAllocationMipmapGenerationControl mips, + RsAllocationMipmapControl mips, uint32_t usages); RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype, - RsAllocationMipmapGenerationControl mips, + RsAllocationMipmapControl mips, const void *data, uint32_t usages); RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype, - RsAllocationMipmapGenerationControl mips, + RsAllocationMipmapControl mips, const void *data, uint32_t usages); #ifndef NO_RS_FUNCS diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java index 897b231..0a06394 100644 --- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java +++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java @@ -34,11 +34,12 @@ public class BallsRS { private ProgramFragment mPFPoints; private ProgramVertex mPV; private ScriptField_Point mPoints; - private ScriptField_Point mArcs; private ScriptField_VpConsts mVpConsts; void updateProjectionMatrices() { - mVpConsts = new ScriptField_VpConsts(mRS, 1); + mVpConsts = new ScriptField_VpConsts(mRS, 1, + Allocation.USAGE_SCRIPT | + Allocation.USAGE_GRAPHICS_CONSTANTS); ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); Matrix4f mvp = new Matrix4f(); mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1); @@ -67,9 +68,10 @@ public class BallsRS { } private Allocation loadTexture(int id) { - final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, - id, Element.RGB_565(mRS), false); - allocation.uploadToTexture(0); + final Allocation allocation = + Allocation.createFromBitmapResource(mRS, mRes, + id, Allocation.MipmapControl.MIPMAP_NONE, + Allocation.USAGE_GRAPHICS_TEXTURE); return allocation; } @@ -88,31 +90,24 @@ public class BallsRS { pfb.setVaryingColor(true); mPFLines = pfb.create(); + android.util.Log.e("rs", "Load texture"); mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0); - mPoints = new ScriptField_Point(mRS, PART_COUNT); - mArcs = new ScriptField_Point(mRS, PART_COUNT * 2); + mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT); Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); smb.addVertexAllocation(mPoints.getAllocation()); smb.addIndexType(Primitive.POINT); Mesh smP = smb.create(); - smb = new Mesh.AllocationBuilder(mRS); - smb.addVertexAllocation(mArcs.getAllocation()); - smb.addIndexType(Primitive.LINE); - Mesh smA = smb.create(); - mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics); mScript = new ScriptC_balls(mRS, mRes, R.raw.balls); mScript.set_partMesh(smP); - mScript.set_arcMesh(smA); mScript.set_physics_script(mPhysicsScript); mScript.bind_point(mPoints); - mScript.bind_arc(mArcs); - mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT)); - mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT)); + mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT)); + mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT)); mScript.set_gPFLines(mPFLines); mScript.set_gPFPoints(mPFPoints); @@ -129,9 +124,7 @@ public class BallsRS { } public void newTouchPosition(float x, float y, float pressure, int id) { - mPhysicsScript.set_touchX(x); - mPhysicsScript.set_touchY(y); - mPhysicsScript.set_touchPressure(pressure); + mPhysicsScript.invoke_touch(x, y, pressure, id); } public void setAccel(float x, float y) { diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsView.java b/libs/rs/java/Balls/src/com/android/balls/BallsView.java index 12f017b..4442eec 100644 --- a/libs/rs/java/Balls/src/com/android/balls/BallsView.java +++ b/libs/rs/java/Balls/src/com/android/balls/BallsView.java @@ -82,6 +82,7 @@ public class BallsView extends RSSurfaceView { int pointerIndex = ev.getActionIndex(); int pointerId = ev.getPointerId(pointerIndex); mRender.newTouchPosition(0, 0, 0, pointerId); + return false; } int count = ev.getHistorySize(); int pcount = ev.getPointerCount(); diff --git a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs index 7c86c67..ff38be5 100644 --- a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs +++ b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs @@ -8,18 +8,22 @@ float2 gGravityVector = {0.f, 9.8f}; float2 gMinPos = {0.f, 0.f}; float2 gMaxPos = {1280.f, 700.f}; -float touchX; -float touchY; -float touchPressure = 0.f; +static float2 touchPos[10]; +static float touchPressure[10]; -void setGamma(float g) { -} +void touch(float x, float y, float pressure, int id) { + if (id >= 10) { + return; + } + touchPos[id].x = x; + touchPos[id].y = y; + touchPressure[id] = pressure; +} void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) { float2 fv = {0, 0}; float2 pos = ballIn->position; - //rsDebug("physics pos in", pos); int arcID = -1; float arcInvStr = 100000; @@ -38,10 +42,6 @@ void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint3 if (len2 > 16 /* (minDist*minDist)*/) { // Repulsion float len = sqrt(len2); - //if (len < arcInvStr) { - //arcInvStr = len; - //arcID = xin; - //} fv -= (vec / (len * len * len)) * 20000.f * forceScale; } else { if (len2 < 1) { @@ -78,12 +78,13 @@ void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint3 fv -= gGravityVector * 4.f; fv *= ctl->dt; - if (touchPressure > 0.1f) { - float2 tp = {touchX, touchY}; - float2 vec = tp - ballIn->position; - float2 vec2 = vec * vec; - float len2 = max(2.f, vec2.x + vec2.y); - fv -= (vec / len2) * touchPressure * 400.f; + for (int i=0; i < 10; i++) { + if (touchPressure[i] > 0.1f) { + float2 vec = touchPos[i] - ballIn->position; + float2 vec2 = vec * vec; + float len2 = max(2.f, vec2.x + vec2.y); + fv -= (vec / len2) * touchPressure[i] * 300.f; + } } ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv; @@ -138,11 +139,6 @@ void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint3 } } - //ballOut->color.b = 1.f; - //ballOut->color.r = min(sqrt(length(ballOut->delta)) * 0.1f, 1.f); - //ballOut->color.g = min(sqrt(length(fv) * 0.1f), 1.f); - //ballOut->arcID = arcID; - //ballOut->arcStr = 8 / arcInvStr; ballOut->size = ballIn->size; //rsDebug("physics pos out", ballOut->position); diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs index c41ed0f..fed9963 100644 --- a/libs/rs/java/Balls/src/com/android/balls/balls.rs +++ b/libs/rs/java/Balls/src/com/android/balls/balls.rs @@ -10,18 +10,14 @@ rs_program_fragment gPFPoints; rs_program_fragment gPFLines; rs_mesh partMesh; -rs_mesh arcMesh; typedef struct __attribute__((packed, aligned(4))) Point { float2 position; - //uchar4 color; float size; } Point_t; Point_t *point; -Point_t *arc; typedef struct VpConsts { - //rs_matrix4x4 Proj; rs_matrix4x4 MVP; } VpConsts_t; VpConsts_t *vpConstants; @@ -42,8 +38,6 @@ void initParts(int w, int h) balls1[ct].position.y = rsRand(0.f, (float)h); balls1[ct].delta.x = 0.f; balls1[ct].delta.y = 0.f; - //balls1[ct].arcID = -1; - //balls1[ct].color = 0.f; balls1[ct].size = 1.f; float r = rsRand(100.f); @@ -76,28 +70,12 @@ int root() { rsForEach(physics_script, bc.ain, bc.aout, &bc); - uint32_t arcIdx = 0; for (uint32_t ct=0; ct < bc.dimX; ct++) { point[ct].position = bout[ct].position; - ///point[ct].color = 0xff;//rsPackColorTo8888(bout[ct].color); point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size; -/* - if (bout[ct].arcID >= 0) { - arc[arcIdx].position = bout[ct].position; - arc[arcIdx].color.r = min(bout[ct].arcStr, 1.f) * 0xff; - arc[arcIdx].color.g = 0; - arc[arcIdx].color.b = 0; - arc[arcIdx].color.a = 0xff; - arc[arcIdx+1].position = bout[bout[ct].arcID].position; - arc[arcIdx+1].color = arc[arcIdx].color; - arcIdx += 2; - } - */ } frame++; - //rsgBindProgramFragment(gPFLines); - //rsgDrawMesh(arcMesh, 0, 0, arcIdx); rsgBindProgramFragment(gPFPoints); rsgDrawMesh(partMesh); rsClearObject(&bc.ain); diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java index e935fa9..5de09f7 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -283,7 +283,7 @@ public class ImageProcessingActivity extends Activity long t = java.lang.System.currentTimeMillis(); if (true) { mScript.invoke_filter(); - mRS.finish(); + mOutPixelsAllocation.copyTo(mBitmapOut); } else { javaFilter(); mDisplayView.invalidate(); @@ -352,7 +352,7 @@ public class ImageProcessingActivity extends Activity public void surfaceCreated(SurfaceHolder holder) { createScript(); mScript.invoke_filter(); - mRS.finish(); + mOutPixelsAllocation.copyTo(mBitmapOut); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { @@ -362,11 +362,15 @@ public class ImageProcessingActivity extends Activity } private void createScript() { - mRS = RenderScript.create(); + mRS = RenderScript.create(this); mRS.setMessageHandler(new FilterCallback()); - mInPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapIn); - mOutPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapOut); + mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, + Allocation.MipmapControl.MIPMAP_NONE, + Allocation.USAGE_SCRIPT); + mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut, + Allocation.MipmapControl.MIPMAP_NONE, + Allocation.USAGE_SCRIPT); Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS)); tb.setX(mBitmapIn.getWidth()); @@ -419,7 +423,7 @@ public class ImageProcessingActivity extends Activity long t = java.lang.System.currentTimeMillis(); mScript.invoke_filter(); - mRS.finish(); + mOutPixelsAllocation.copyTo(mBitmapOut); t = java.lang.System.currentTimeMillis() - t; android.util.Log.v("Img", "Renderscript frame time core ms " + t); @@ -432,6 +436,6 @@ public class ImageProcessingActivity extends Activity mScript.set_radius(mRadius); mScript.invoke_filter(); - mRS.finish(); + mOutPixelsAllocation.copyTo(mBitmapOut); } } diff --git a/libs/rs/java/Samples/AndroidManifest.xml b/libs/rs/java/Samples/AndroidManifest.xml index be191f2..6f35e2a 100644 --- a/libs/rs/java/Samples/AndroidManifest.xml +++ b/libs/rs/java/Samples/AndroidManifest.xml @@ -20,5 +20,14 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + + <activity android:name="RsBench" + android:label="RsBenchmark" + 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> diff --git a/libs/rs/java/Samples/res/raw/multitexf.glsl b/libs/rs/java/Samples/res/raw/multitexf.glsl index 351ff9b..e492a47 100644 --- a/libs/rs/java/Samples/res/raw/multitexf.glsl +++ b/libs/rs/java/Samples/res/raw/multitexf.glsl @@ -7,6 +7,7 @@ void main() { lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba; col0.xyz = col0.xyz*col1.xyz*1.5; col0.xyz = mix(col0.xyz, col2.xyz, col2.w); + col0.w = 0.5; gl_FragColor = col0; } diff --git a/libs/rs/java/Samples/res/raw/shader2f.glsl b/libs/rs/java/Samples/res/raw/shader2f.glsl new file mode 100644 index 0000000..5fc05f1 --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shader2f.glsl @@ -0,0 +1,29 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(-varWorldPos.xyz); + vec3 worldNorm = normalize(varWorldNormal); + + vec3 light0Vec = normalize(UNI_light0_Posision.xyz - varWorldPos); + vec3 light0R = -reflect(light0Vec, worldNorm); + float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse; + float light0Spec = clamp(dot(light0R, V), 0.001, 1.0); + float light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular; + + vec3 light1Vec = normalize(UNI_light1_Posision.xyz - varWorldPos); + vec3 light1R = reflect(light1Vec, worldNorm); + float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse; + float light1Spec = clamp(dot(light1R, V), 0.001, 1.0); + float light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular; + + vec2 t0 = varTex0.xy; + lowp vec4 col = texture2D(UNI_Tex0, t0).rgba; + col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz); + col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz; + col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz; + gl_FragColor = col; +} + diff --git a/libs/rs/java/Samples/res/raw/shader2movev.glsl b/libs/rs/java/Samples/res/raw/shader2movev.glsl new file mode 100644 index 0000000..68712e6 --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shader2movev.glsl @@ -0,0 +1,22 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +// This is where actual shader code begins +void main() { + vec4 objPos = ATTRIB_position; + vec3 oldPos = objPos.xyz; + objPos.xyz += 0.1*sin(objPos.xyz*2.0 + UNI_time); + objPos.xyz += 0.05*sin(objPos.xyz*4.0 + UNI_time*0.5); + objPos.xyz += 0.02*sin(objPos.xyz*7.0 + UNI_time*0.75); + vec4 worldPos = UNI_model * objPos; + gl_Position = UNI_proj * worldPos; + + mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz); + vec3 worldNorm = model3 * (ATTRIB_normal + oldPos - objPos.xyz); + //vec3 worldNorm = model3 * ATTRIB_normal; + + varWorldPos = worldPos.xyz; + varWorldNormal = worldNorm; + varTex0 = ATTRIB_texture0; +} diff --git a/libs/rs/java/Samples/res/raw/shader2v.glsl b/libs/rs/java/Samples/res/raw/shader2v.glsl new file mode 100644 index 0000000..e6885a3 --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shader2v.glsl @@ -0,0 +1,17 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +// This is where actual shader code begins +void main() { + vec4 objPos = ATTRIB_position; + vec4 worldPos = UNI_model * objPos; + gl_Position = UNI_proj * worldPos; + + mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz); + vec3 worldNorm = model3 * ATTRIB_normal; + + varWorldPos = worldPos.xyz; + varWorldNormal = worldNorm; + varTex0 = ATTRIB_texture0; +} diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBench.java b/libs/rs/java/Samples/src/com/android/samples/RsBench.java new file mode 100644 index 0000000..5b9af6f --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsBench.java @@ -0,0 +1,71 @@ +/* + * 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.samples; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +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.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class RsBench extends Activity { + + private RsBenchView 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 RsBenchView(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(); + } + +} + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java new file mode 100644 index 0000000..212e7a8 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java @@ -0,0 +1,418 @@ +/* + * 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.samples; + +import java.io.Writer; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.renderscript.*; +import android.renderscript.Allocation.CubemapLayout; +import android.renderscript.Program.TextureType; +import android.renderscript.ProgramStore.DepthFunc; +import android.renderscript.Sampler.Value; +import android.util.Log; + + +public class RsBenchRS { + + int mWidth; + int mHeight; + + public RsBenchRS() { + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + mOptionsARGB.inScaled = false; + mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; + mMode = 0; + mMaxModes = 0; + initRS(); + } + + private Resources mRes; + private RenderScriptGL mRS; + + private Sampler mLinearClamp; + private Sampler mLinearWrap; + private Sampler mMipLinearWrap; + private Sampler mNearestClamp; + private Sampler mMipLinearAniso8; + private Sampler mMipLinearAniso15; + + private ProgramStore mProgStoreBlendNoneDepth; + private ProgramStore mProgStoreBlendNone; + private ProgramStore mProgStoreBlendAlpha; + private ProgramStore mProgStoreBlendAdd; + + private ProgramFragment mProgFragmentTexture; + private ProgramFragment mProgFragmentColor; + + private ProgramVertex mProgVertex; + private ProgramVertex.MatrixAllocation mPVA; + + // Custom shaders + private ProgramVertex mProgVertexCustom; + private ProgramFragment mProgFragmentCustom; + private ProgramFragment mProgFragmentMultitex; + private ProgramVertex mProgVertexPixelLight; + private ProgramVertex mProgVertexPixelLightMove; + private ProgramFragment mProgFragmentPixelLight; + private ScriptField_VertexShaderConstants_s mVSConst; + private ScriptField_FragentShaderConstants_s mFSConst; + private ScriptField_VertexShaderConstants3_s mVSConstPixel; + private ScriptField_FragentShaderConstants3_s mFSConstPixel; + + private ProgramVertex mProgVertexCube; + private ProgramFragment mProgFragmentCube; + + private ProgramRaster mCullBack; + private ProgramRaster mCullFront; + private ProgramRaster mCullNone; + + private Allocation mTexTorus; + private Allocation mTexOpaque; + private Allocation mTexTransparent; + private Allocation mTexChecker; + private Allocation mTexCube; + + private Mesh m10by10Mesh; + private Mesh m100by100Mesh; + private Mesh mWbyHMesh; + private Mesh mTorus; + + Font mFontSans; + Font mFontSerif; + Font mFontSerifBold; + Font mFontSerifItalic; + Font mFontSerifBoldItalic; + Font mFontMono; + private Allocation mTextAlloc; + + private ScriptC_rsbench mScript; + + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + + int mMode; + int mMaxModes; + + public void onActionDown(int x, int y) { + mMode ++; + mMode = mMode % mMaxModes; + mScript.set_gDisplayMode(mMode); + } + + private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) { + + Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, + 2, Mesh.TriangleMeshBuilder.TEXTURE_0); + + for (int y = 0; y <= hResolution; y++) { + final float normalizedY = (float)y / hResolution; + final float yOffset = (normalizedY - 0.5f) * height; + for (int x = 0; x <= wResolution; x++) { + float normalizedX = (float)x / wResolution; + float xOffset = (normalizedX - 0.5f) * width; + tmb.setTexture((float)x % 2, (float)y % 2); + tmb.addVertex(xOffset, yOffset); + } + } + + for (int y = 0; y < hResolution; y++) { + final int curY = y * (wResolution + 1); + final int belowY = (y + 1) * (wResolution + 1); + for (int x = 0; x < wResolution; x++) { + int curV = curY + x; + int belowV = belowY + x; + tmb.addTriangle(curV, belowV, curV + 1); + tmb.addTriangle(belowV, belowV + 1, curV + 1); + } + } + + return tmb.create(true); + } + + private void initProgramStore() { + // Use stock the stock program store object + mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS); + mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NO_DEPTH(mRS); + + // Create a custom program store + ProgramStore.Builder builder = new ProgramStore.Builder(mRS); + builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, + ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); + builder.setDitherEnable(false); + builder.setDepthMask(false); + mProgStoreBlendAlpha = builder.create(); + + mProgStoreBlendAdd = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS); + + mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth); + mScript.set_gProgStoreBlendNone(mProgStoreBlendNone); + mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha); + mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd); + } + + private void initProgramFragment() { + + ProgramFragment.Builder texBuilder = new ProgramFragment.Builder(mRS); + texBuilder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, + ProgramFragment.Builder.Format.RGBA, 0); + mProgFragmentTexture = texBuilder.create(); + mProgFragmentTexture.bindSampler(mLinearClamp, 0); + + ProgramFragment.Builder colBuilder = new ProgramFragment.Builder(mRS); + colBuilder.setVaryingColor(false); + mProgFragmentColor = colBuilder.create(); + + mScript.set_gProgFragmentColor(mProgFragmentColor); + mScript.set_gProgFragmentTexture(mProgFragmentTexture); + } + + private void initProgramVertex() { + ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS); + mProgVertex = pvb.create(); + + mPVA = new ProgramVertex.MatrixAllocation(mRS); + mProgVertex.bindAllocation(mPVA); + mPVA.setupOrthoWindow(mWidth, mHeight); + + mScript.set_gProgVertex(mProgVertex); + } + + private void initCustomShaders() { + mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1); + mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1); + mScript.bind_gVSConstants(mVSConst); + mScript.bind_gFSConstants(mFSConst); + + mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1); + mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1); + mScript.bind_gVSConstPixel(mVSConstPixel); + mScript.bind_gFSConstPixel(mFSConstPixel); + + // Initialize the shader builder + ProgramVertex.ShaderBuilder pvbCustom = new ProgramVertex.ShaderBuilder(mRS); + // Specify the resource that contains the shader string + pvbCustom.setShader(mRes, R.raw.shaderv); + // Use a script field to spcify the input layout + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + // Define the constant input layout + pvbCustom.addConstant(mVSConst.getAllocation().getType()); + mProgVertexCustom = pvbCustom.create(); + // Bind the source of constant data + mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0); + + ProgramFragment.ShaderBuilder pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + // Specify the resource that contains the shader string + pfbCustom.setShader(mRes, R.raw.shaderf); + //Tell the builder how many textures we have + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + // Define the constant input layout + pfbCustom.addConstant(mFSConst.getAllocation().getType()); + mProgFragmentCustom = pfbCustom.create(); + // Bind the source of constant data + mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0); + + // Cubemap test shaders + pvbCustom = new ProgramVertex.ShaderBuilder(mRS); + pvbCustom.setShader(mRes, R.raw.shadercubev); + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + pvbCustom.addConstant(mVSConst.getAllocation().getType()); + mProgVertexCube = pvbCustom.create(); + mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0); + + pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + pfbCustom.setShader(mRes, R.raw.shadercubef); + pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE); + mProgFragmentCube = pfbCustom.create(); + + pvbCustom = new ProgramVertex.ShaderBuilder(mRS); + pvbCustom.setShader(mRes, R.raw.shader2v); + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + pvbCustom.addConstant(mVSConstPixel.getAllocation().getType()); + mProgVertexPixelLight = pvbCustom.create(); + mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0); + + pvbCustom = new ProgramVertex.ShaderBuilder(mRS); + pvbCustom.setShader(mRes, R.raw.shader2movev); + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + pvbCustom.addConstant(mVSConstPixel.getAllocation().getType()); + mProgVertexPixelLightMove = pvbCustom.create(); + mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0); + + pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + pfbCustom.setShader(mRes, R.raw.shader2f); + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + pfbCustom.addConstant(mFSConstPixel.getAllocation().getType()); + mProgFragmentPixelLight = pfbCustom.create(); + mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0); + + pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + pfbCustom.setShader(mRes, R.raw.multitexf); + pfbCustom.setTextureCount(3); + mProgFragmentMultitex = pfbCustom.create(); + + mScript.set_gProgVertexCustom(mProgVertexCustom); + mScript.set_gProgFragmentCustom(mProgFragmentCustom); + mScript.set_gProgVertexCube(mProgVertexCube); + mScript.set_gProgFragmentCube(mProgFragmentCube); + mScript.set_gProgVertexPixelLight(mProgVertexPixelLight); + mScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove); + mScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight); + mScript.set_gProgFragmentMultitex(mProgFragmentMultitex); + } + + private Allocation loadTextureRGB(int id) { + final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, + id, Element.RGB_565(mRS), true); + allocation.uploadToTexture(0); + return allocation; + } + + private Allocation loadTextureARGB(int id) { + Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB); + final Allocation allocation = Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true); + allocation.uploadToTexture(0); + return allocation; + } + + private void loadImages() { + mTexTorus = loadTextureRGB(R.drawable.torusmap); + mTexOpaque = loadTextureRGB(R.drawable.data); + mTexTransparent = loadTextureARGB(R.drawable.leaf); + mTexChecker = loadTextureRGB(R.drawable.checker); + Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test); + mTexCube = Allocation.createCubemapFromBitmap(mRS, b, Element.RGB_565(mRS), false, + Allocation.CubemapLayout.VERTICAL_FACE_LIST); + mTexCube.uploadToTexture(0); + + mScript.set_gTexTorus(mTexTorus); + mScript.set_gTexOpaque(mTexOpaque); + mScript.set_gTexTransparent(mTexTransparent); + mScript.set_gTexChecker(mTexChecker); + mScript.set_gTexCube(mTexCube); + } + + private void initFonts() { + // Sans font by family name + mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8); + // Create font by file name + mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8); + // Create fonts by family and style + mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8); + mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.ITALIC, 8); + mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8); + mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8); + + mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT); + + mScript.set_gFontSans(mFontSans); + mScript.set_gFontSerif(mFontSerif); + mScript.set_gFontSerifBold(mFontSerifBold); + mScript.set_gFontSerifItalic(mFontSerifItalic); + mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic); + mScript.set_gFontMono(mFontMono); + mScript.set_gTextAlloc(mTextAlloc); + } + + private void initMesh() { + m10by10Mesh = getMbyNMesh(mWidth, mHeight, 10, 10); + mScript.set_g10by10Mesh(m10by10Mesh); + m100by100Mesh = getMbyNMesh(mWidth, mHeight, 100, 100); + mScript.set_g100by100Mesh(m100by100Mesh); + mWbyHMesh= getMbyNMesh(mWidth, mHeight, mWidth/4, mHeight/4); + mScript.set_gWbyHMesh(mWbyHMesh); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if (entry == null || entry.getClassID() != FileA3D.ClassID.MESH) { + Log.e("rs", "could not load model"); + } else { + mTorus = (Mesh)entry.getObject(); + mScript.set_gTorusMesh(mTorus); + } + } + + private void initSamplers() { + Sampler.Builder bs = new Sampler.Builder(mRS); + bs.setMin(Sampler.Value.LINEAR); + bs.setMag(Sampler.Value.LINEAR); + bs.setWrapS(Sampler.Value.WRAP); + bs.setWrapT(Sampler.Value.WRAP); + mLinearWrap = bs.create(); + + mLinearClamp = Sampler.CLAMP_LINEAR(mRS); + mNearestClamp = Sampler.CLAMP_NEAREST(mRS); + mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS); + + bs = new Sampler.Builder(mRS); + bs.setMin(Sampler.Value.LINEAR_MIP_LINEAR); + bs.setMag(Sampler.Value.LINEAR); + bs.setWrapS(Sampler.Value.WRAP); + bs.setWrapT(Sampler.Value.WRAP); + bs.setAnisotropy(8.0f); + mMipLinearAniso8 = bs.create(); + bs.setAnisotropy(15.0f); + mMipLinearAniso15 = bs.create(); + + mScript.set_gLinearClamp(mLinearClamp); + mScript.set_gLinearWrap(mLinearWrap); + mScript.set_gMipLinearWrap(mMipLinearWrap); + mScript.set_gMipLinearAniso8(mMipLinearAniso8); + mScript.set_gMipLinearAniso15(mMipLinearAniso15); + mScript.set_gNearestClamp(mNearestClamp); + } + + private void initProgramRaster() { + mCullBack = ProgramRaster.CULL_BACK(mRS); + mCullFront = ProgramRaster.CULL_FRONT(mRS); + mCullNone = ProgramRaster.CULL_NONE(mRS); + + mScript.set_gCullBack(mCullBack); + mScript.set_gCullFront(mCullFront); + mScript.set_gCullNone(mCullNone); + } + + private void initRS() { + + mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench); + + mMaxModes = mScript.get_gMaxModes(); + + initSamplers(); + initProgramStore(); + initProgramFragment(); + initProgramVertex(); + initFonts(); + loadImages(); + initMesh(); + initProgramRaster(); + initCustomShaders(); + + mRS.bindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java b/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java new file mode 100644 index 0000000..4283a42 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java @@ -0,0 +1,96 @@ +/* + * 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.samples; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RsBenchView extends RSSurfaceView { + + public RsBenchView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private RsBenchRS mRender; + + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + sc.setDepth(16, 24); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new RsBenchRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mRS != null) { + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = false; + int act = ev.getAction(); + if (act == ev.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + ret = true; + } + + return ret; + } +} + + diff --git a/libs/rs/java/Samples/src/com/android/samples/rsbench.rs b/libs/rs/java/Samples/src/com/android/samples/rsbench.rs new file mode 100644 index 0000000..87f2f29 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/rsbench.rs @@ -0,0 +1,845 @@ +// Copyright (C) 2009 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.samples) + +#include "rs_graphics.rsh" +#include "shader_def.rsh" + +const int gMaxModes = 23; + +rs_program_vertex gProgVertex; +rs_program_fragment gProgFragmentColor; +rs_program_fragment gProgFragmentTexture; + +rs_program_store gProgStoreBlendNoneDepth; +rs_program_store gProgStoreBlendNone; +rs_program_store gProgStoreBlendAlpha; +rs_program_store gProgStoreBlendAdd; + +rs_allocation gTexOpaque; +rs_allocation gTexTorus; +rs_allocation gTexTransparent; +rs_allocation gTexChecker; +rs_allocation gTexCube; + +rs_mesh g10by10Mesh; +rs_mesh g100by100Mesh; +rs_mesh gWbyHMesh; +rs_mesh gTorusMesh; + +rs_font gFontSans; +rs_font gFontSerif; +rs_font gFontSerifBold; +rs_font gFontSerifItalic; +rs_font gFontSerifBoldItalic; +rs_font gFontMono; +rs_allocation gTextAlloc; + +int gDisplayMode; + +rs_sampler gLinearClamp; +rs_sampler gLinearWrap; +rs_sampler gMipLinearWrap; +rs_sampler gMipLinearAniso8; +rs_sampler gMipLinearAniso15; +rs_sampler gNearestClamp; + +rs_program_raster gCullBack; +rs_program_raster gCullFront; +rs_program_raster gCullNone; + +// Custom vertex shader compunents +VertexShaderConstants *gVSConstants; +FragentShaderConstants *gFSConstants; +VertexShaderConstants3 *gVSConstPixel; +FragentShaderConstants3 *gFSConstPixel; +// Export these out to easily set the inputs to shader +VertexShaderInputs *gVSInputs; +// Custom shaders we use for lighting +rs_program_vertex gProgVertexCustom; +rs_program_fragment gProgFragmentCustom; +rs_program_vertex gProgVertexPixelLight; +rs_program_vertex gProgVertexPixelLightMove; +rs_program_fragment gProgFragmentPixelLight; +rs_program_vertex gProgVertexCube; +rs_program_fragment gProgFragmentCube; +rs_program_fragment gProgFragmentMultitex; + +float gDt = 0; + +void init() { +} + +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}; +static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f, + 0.5f, 0.7f, 0.5f, 1.0f, + 0.7f, 0.5f, 0.5f, 1.0f, + 0.5f, 0.5f, 0.7f, 1.0f, + 0.5f, 0.6f, 0.7f, 1.0f, +}; + +void displayFontSamples(int fillNum) { + + uint width = rsgGetWidth(); + uint height = rsgGetHeight(); + int left = 0, right = 0, top = 0, bottom = 0; + rsgMeasureText(sampleText, &left, &right, &top, &bottom); + + int textHeight = top - bottom; + int textWidth = right - left; + int numVerticalLines = height / textHeight; + int yPos = top; + + int xOffset = 0, yOffset = 0; + rsgBindFont(gFontSans); //rsgBindFont(gFontSerif); rsgBindFont(gFontSerifBold); rsgBindFont(gFontSerifBoldItalic); rsgBindFont(gFontSans); + + for(int fillI = 0; fillI < fillNum; fillI ++) { + xOffset = textOffsets[fillI * 2]; + yOffset = textOffsets[fillI * 2 + 1]; + float *colPtr = textColors + fillI * 4; + rsgFontColor(colPtr[0], colPtr[1], colPtr[2], colPtr[3]); + for (int h = 0; h < 4; h ++) { + yPos = top + yOffset; + for (int v = 0; v < numVerticalLines; v ++) { + rsgDrawText(sampleText, xOffset + textWidth * h, yPos); + yPos += textHeight; + } + } + } +} + +void bindProgramVertexOrtho() { + // Default vertex sahder + rsgBindProgramVertex(gProgVertex); + // Setup the projectioni matrix + rs_matrix4x4 proj; + rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500); + rsgProgramVertexLoadProjectionMatrix(&proj); +} + +void displaySingletexFill(bool blend, int quadCount) { + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + if (!blend) { + rsgBindProgramStore(gProgStoreBlendNone); + } else { + rsgBindProgramStore(gProgStoreBlendAlpha); + } + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + for (int i = 0; i < quadCount; i ++) { + float startX = 10 * i, startY = 10 * i; + float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + } +} + +void displayBlendingSamples() { + int i; + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + rsgBindProgramFragment(gProgFragmentColor); + + rsgBindProgramStore(gProgStoreBlendNone); + for (i = 0; i < 3; i ++) { + float iPlusOne = (float)(i + 1); + rsgProgramFragmentConstantColor(gProgFragmentColor, + 0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1); + float yPos = 150 * (float)i; + rsgDrawRect(0, yPos, 200, yPos + 200, 0); + } + + rsgBindProgramStore(gProgStoreBlendAlpha); + for (i = 0; i < 3; i ++) { + float iPlusOne = (float)(i + 1); + rsgProgramFragmentConstantColor(gProgFragmentColor, + 0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5); + float yPos = 150 * (float)i; + rsgDrawRect(150, yPos, 350, yPos + 200, 0); + } + + rsgBindProgramStore(gProgStoreBlendAdd); + for (i = 0; i < 3; i ++) { + float iPlusOne = (float)(i + 1); + rsgProgramFragmentConstantColor(gProgFragmentColor, + 0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5); + float yPos = 150 * (float)i; + rsgDrawRect(300, yPos, 500, yPos + 200, 0); + } + + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("No Blending", 10, 50); + rsgDrawText("Alpha Blending", 160, 150); + rsgDrawText("Additive Blending", 320, 250); + +} + +void displayMeshSamples(int meshNum) { + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadTranslate(&matrix, rsgGetWidth()/2, rsgGetHeight()/2, 0); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + if (meshNum == 0) { + rsgDrawMesh(g10by10Mesh); + } else if (meshNum == 1) { + rsgDrawMesh(g100by100Mesh); + } else if (meshNum == 2) { + rsgDrawMesh(gWbyHMesh); + } +} + +void displayTextureSamplers() { + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + // Linear clamp + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + float startX = 0, startY = 0; + float width = 300, height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.1, + startX + width, startY + height, 0, 1.1, 1.1, + startX + width, startY, 0, 1.1, 0); + + // Linear Wrap + rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap); + startX = 0; startY = 300; + width = 300; height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.1, + startX + width, startY + height, 0, 1.1, 1.1, + startX + width, startY, 0, 1.1, 0); + + // Nearest + rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp); + startX = 300; startY = 0; + width = 300; height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.1, + startX + width, startY + height, 0, 1.1, 1.1, + startX + width, startY, 0, 1.1, 0); + + rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap); + startX = 300; startY = 300; + width = 300; height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.5, + startX + width, startY + height, 0, 1.5, 1.5, + startX + width, startY, 0, 1.5, 0); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Filtering: linear clamp", 10, 290); + rsgDrawText("Filtering: linear wrap", 10, 590); + rsgDrawText("Filtering: nearest clamp", 310, 290); + rsgDrawText("Filtering: miplinear wrap", 310, 590); +} + +float gTorusRotation = 0; +static void drawToruses(int numMeshes) { + rs_matrix4x4 matrix; + + if (numMeshes == 1) { + rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -7.5f); + rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgDrawMesh(gTorusMesh); + return; + } + + if (numMeshes == 2) { + rsMatrixLoadTranslate(&matrix, -1.6f, 0.0f, -7.5f); + rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgDrawMesh(gTorusMesh); + + rsMatrixLoadTranslate(&matrix, 1.6f, 0.0f, -7.5f); + rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgDrawMesh(gTorusMesh); + return; + } + + float startX = -5.0f; + float startY = -1.5f; + float startZ = -15.0f; + float dist = 3.2f; + + for (int h = 0; h < 4; h ++) { + for (int v = 0; v < 2; v ++) { + // Position our model on the screen + rsMatrixLoadTranslate(&matrix, startX + dist * h, startY + dist * v, startZ); + rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgDrawMesh(gTorusMesh); + } + } +} + + +// Quick hack to get some geometry numbers +void displaySimpleGeoSamples(bool useTexture, int numMeshes) { + rsgBindProgramVertex(gProgVertex); + rsgBindProgramRaster(gCullBack); + // Setup the projectioni matrix with 60 degree field of view + rs_matrix4x4 proj; + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNoneDepth); + if (useTexture) { + rsgBindProgramFragment(gProgFragmentTexture); + } else { + rsgBindProgramFragment(gProgFragmentColor); + rsgProgramFragmentConstantColor(gProgFragmentColor, 0.1, 0.7, 0.1, 1); + } + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexTorus); + + // Aplly a rotation to our mesh + gTorusRotation += 50.0f * gDt; + if (gTorusRotation > 360.0f) { + gTorusRotation -= 360.0f; + } + + drawToruses(numMeshes); +} + +float gLight0Rotation = 0; +float gLight1Rotation = 0; + +void setupCustomShaderLights() { + float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f}; + float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f}; + float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f}; + float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f}; + float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f}; + float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f}; + + gLight0Rotation += 50.0f * gDt; + if (gLight0Rotation > 360.0f) { + gLight0Rotation -= 360.0f; + } + gLight1Rotation -= 50.0f * gDt; + if (gLight1Rotation > 360.0f) { + gLight1Rotation -= 360.0f; + } + + rs_matrix4x4 l0Mat; + rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f); + light0Pos = rsMatrixMultiply(&l0Mat, light0Pos); + rs_matrix4x4 l1Mat; + rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f); + light1Pos = rsMatrixMultiply(&l1Mat, light1Pos); + + // Set light 0 properties + gVSConstants->light0_Posision = light0Pos; + gVSConstants->light0_Diffuse = 1.0f; + gVSConstants->light0_Specular = 0.5f; + gVSConstants->light0_CosinePower = 10.0f; + // Set light 1 properties + gVSConstants->light1_Posision = light1Pos; + gVSConstants->light1_Diffuse = 1.0f; + gVSConstants->light1_Specular = 0.7f; + gVSConstants->light1_CosinePower = 25.0f; + rsAllocationMarkDirty(rsGetAllocation(gVSConstants)); + + // Update fragmetn shader constants + // Set light 0 colors + gFSConstants->light0_DiffuseColor = light0DiffCol; + gFSConstants->light0_SpecularColor = light0SpecCol; + // Set light 1 colors + gFSConstants->light1_DiffuseColor = light1DiffCol; + gFSConstants->light1_SpecularColor = light1SpecCol; + rsAllocationMarkDirty(rsGetAllocation(gFSConstants)); + + // Set light 0 properties for per pixel lighting + gFSConstPixel->light0_Posision = light0Pos; + gFSConstPixel->light0_Diffuse = 1.0f; + gFSConstPixel->light0_Specular = 0.5f; + gFSConstPixel->light0_CosinePower = 10.0f; + gFSConstPixel->light0_DiffuseColor = light0DiffCol; + gFSConstPixel->light0_SpecularColor = light0SpecCol; + // Set light 1 properties + gFSConstPixel->light1_Posision = light1Pos; + gFSConstPixel->light1_Diffuse = 1.0f; + gFSConstPixel->light1_Specular = 0.7f; + gFSConstPixel->light1_CosinePower = 25.0f; + gFSConstPixel->light1_DiffuseColor = light1DiffCol; + gFSConstPixel->light1_SpecularColor = light1SpecCol; + rsAllocationMarkDirty(rsGetAllocation(gFSConstPixel)); +} + +void displayCustomShaderSamples(int numMeshes) { + + // Update vertex shader constants + // Load model matrix + // Aplly a rotation to our mesh + gTorusRotation += 50.0f * gDt; + if (gTorusRotation > 360.0f) { + gTorusRotation -= 360.0f; + } + + // Setup the projectioni matrix + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f); + setupCustomShaderLights(); + + rsgBindProgramVertex(gProgVertexCustom); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNoneDepth); + rsgBindProgramFragment(gProgFragmentCustom); + rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp); + rsgBindTexture(gProgFragmentCustom, 0, gTexTorus); + + // Use back face culling + rsgBindProgramRaster(gCullBack); + + rs_matrix4x4 matrix; + + if (numMeshes == 1) { + rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -7.5f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstants)); + + rsgDrawMesh(gTorusMesh); + return; + } + + if (numMeshes == 2) { + rsMatrixLoadTranslate(&gVSConstants->model, -1.6f, 0.0f, -7.5f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstants)); + rsgDrawMesh(gTorusMesh); + + rsMatrixLoadTranslate(&gVSConstants->model, 1.6f, 0.0f, -7.5f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstants)); + rsgDrawMesh(gTorusMesh); + return; + } + + float startX = -5.0f; + float startY = -1.5f; + float startZ = -15.0f; + float dist = 3.2f; + + for (int h = 0; h < 4; h ++) { + for (int v = 0; v < 2; v ++) { + // Position our model on the screen + rsMatrixLoadTranslate(&gVSConstants->model, startX + dist * h, startY + dist * v, startZ); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstants)); + rsgDrawMesh(gTorusMesh); + } + } +} + +void displayPixelLightSamples(int numMeshes) { + + // Update vertex shader constants + // Load model matrix + // Aplly a rotation to our mesh + gTorusRotation += 20.0f * gDt; + if (gTorusRotation > 360.0f) { + gTorusRotation -= 360.0f; + } + + //gTorusRotation = 45.0f; + + gVSConstPixel->time = rsUptimeMillis()*0.005; + + // Setup the projectioni matrix + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f); + setupCustomShaderLights(); + + rsgBindProgramVertex(gProgVertexPixelLight); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNoneDepth); + rsgBindProgramFragment(gProgFragmentPixelLight); + rsgBindSampler(gProgFragmentPixelLight, 0, gLinearClamp); + rsgBindTexture(gProgFragmentPixelLight, 0, gTexTorus); + + // Use back face culling + rsgBindProgramRaster(gCullBack); + + rs_matrix4x4 matrix; + + if (numMeshes == 1) { + rsMatrixLoadTranslate(&gVSConstPixel->model, 0.0f, 0.0f, -7.5f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel)); + + rsgDrawMesh(gTorusMesh); + return; + } + + if (numMeshes == 2) { + rsMatrixLoadTranslate(&gVSConstPixel->model, -1.6f, 0.0f, -7.5f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel)); + rsgDrawMesh(gTorusMesh); + + rsMatrixLoadTranslate(&gVSConstPixel->model, 1.6f, 0.0f, -7.5f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel)); + rsgDrawMesh(gTorusMesh); + return; + } + + float startX = -5.0f; + float startY = -1.5f; + float startZ = -15.0f; + float dist = 3.2f; + + for (int h = 0; h < 4; h ++) { + for (int v = 0; v < 2; v ++) { + // Position our model on the screen + rsMatrixLoadTranslate(&gVSConstPixel->model, startX + dist * h, startY + dist * v, startZ); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&gVSConstPixel->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + rsAllocationMarkDirty(rsGetAllocation(gVSConstPixel)); + rsgDrawMesh(gTorusMesh); + } + } +} + +void displayMultitextureSample(bool blend, int quadCount) { + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + if (!blend) { + rsgBindProgramStore(gProgStoreBlendNone); + } else { + rsgBindProgramStore(gProgStoreBlendAlpha); + } + rsgBindProgramFragment(gProgFragmentMultitex); + rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp); + rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap); + rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp); + rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker); + rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus); + rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent); + + for (int i = 0; i < quadCount; i ++) { + float startX = 10 * i, startY = 10 * i; + float width = rsgGetWidth() - startX, height = rsgGetHeight() - startY; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + } +} + +float gAnisoTime = 0.0f; +uint anisoMode = 0; +void displayAnisoSample() { + + gAnisoTime += gDt; + + rsgBindProgramVertex(gProgVertex); + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rs_matrix4x4 proj; + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rs_matrix4x4 matrix; + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f); + rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + + rsgBindProgramRaster(gCullNone); + + rsgBindTexture(gProgFragmentTexture, 0, gTexChecker); + + if (gAnisoTime >= 5.0f) { + gAnisoTime = 0.0f; + anisoMode ++; + anisoMode = anisoMode % 3; + } + + if (anisoMode == 0) { + rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8); + } else if (anisoMode == 1) { + rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15); + } else { + rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap); + } + + float startX = -15; + float startY = -15; + float width = 30; + float height = 30; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 10, + startX + width, startY + height, 0, 10, 10, + startX + width, startY, 0, 10, 0); + + rsgBindProgramRaster(gCullBack); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + if (anisoMode == 0) { + rsgDrawText("Anisotropic filtering 8", 10, 40); + } else if (anisoMode == 1) { + rsgDrawText("Anisotropic filtering 15", 10, 40); + } else { + rsgDrawText("Miplinear filtering", 10, 40); + } +} + +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); + displaySingletexFill(true, 3); + displayBlendingSamples(); + displayMeshSamples(0); + displayMeshSamples(1); + displayMeshSamples(2); + displayTextureSamplers(); + displayMultitextureSample(true, 5); + displayAnisoSample(); + 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); + + return false; + } + + return true; +} + +static int frameCount = 0; +static int totalFramesRendered = 0; +static int benchMode = 0; + +#define testTime 10.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 simpleGeo", + "Finished simpleGeo", + "Finished simpleGeo", + "Finished simpleGeo", + "Finished simpleGeo", + "Finished simpleGeo", +}; + +int root(int launchID) { + + gDt = rsGetDt(); + + rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f); + rsgClearDepth(1.0f); + + if(!checkInit()) { + return 1; + } + + /*displayPixelLightSamples(1); + 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) { + case 0: + displayFontSamples(1); + break; + case 1: + displayFontSamples(2); + break; + case 2: + displayFontSamples(3); + break; + case 3: + displayFontSamples(4); + break; + case 4: + displayFontSamples(5); + break; + case 5: + displaySimpleGeoSamples(false, 1); + break; + case 6: + displaySimpleGeoSamples(false, 2); + break; + case 7: + displaySimpleGeoSamples(false, 8); + break; + case 8: + displaySimpleGeoSamples(true, 1); + break; + case 9: + displaySimpleGeoSamples(true, 2); + break; + case 10: + displaySimpleGeoSamples(true, 8); + break; + case 11: + displayMeshSamples(0); + break; + case 12: + displayMeshSamples(1); + break; + case 13: + displayMeshSamples(2); + break; + case 14: + displayCustomShaderSamples(1); + break; + case 15: + displayCustomShaderSamples(2); + break; + case 16: + displayCustomShaderSamples(8); + break; + case 17: + displaySingletexFill(false, 5); + break; + case 18: + displayMultitextureSample(false, 5); + break; + case 19: + displaySingletexFill(true, 5); + break; + case 20: + displayMultitextureSample(true, 5); + break; + case 21: + displayPixelLightSamples(1); + break; + case 22: + displayPixelLightSamples(2); + break; + case 23: + displayPixelLightSamples(8); + break; + } + + frameCount ++; + + return 1; +} diff --git a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh index 3f51785..1d804c6 100644 --- a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh +++ b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh @@ -39,6 +39,13 @@ typedef struct VertexShaderConstants2_s { float light_CosinePower[2]; } VertexShaderConstants2; +typedef struct VertexShaderConstants3_s { + rs_matrix4x4 model; + rs_matrix4x4 proj; + float time; +} VertexShaderConstants3; + + typedef struct FragentShaderConstants_s { float4 light0_DiffuseColor; float4 light0_SpecularColor; @@ -52,6 +59,22 @@ typedef struct FragentShaderConstants2_s { float4 light_SpecularColor[2]; } FragentShaderConstants2; +typedef struct FragentShaderConstants3_s { + float4 light0_DiffuseColor; + float4 light0_SpecularColor; + float4 light0_Posision; + float light0_Diffuse; + float light0_Specular; + float light0_CosinePower; + + float4 light1_DiffuseColor; + float4 light1_SpecularColor; + float4 light1_Posision; + float light1_Diffuse; + float light1_Specular; + float light1_CosinePower; +} FragentShaderConstants3; + typedef struct VertexShaderInputs_s { float4 position; float3 normal; diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java index 11b0fcd..265e1d6 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java +++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java @@ -16,6 +16,7 @@ package com.android.rs.test; +import android.content.Context; import android.content.res.Resources; import android.renderscript.*; import android.util.Log; @@ -28,8 +29,10 @@ import java.util.TimerTask; public class RSTestCore { int mWidth; int mHeight; + Context mCtx; - public RSTestCore() { + public RSTestCore(Context ctx) { + mCtx = ctx; } private Resources mRes; @@ -61,11 +64,10 @@ public class RSTestCore { unitTests = new ArrayList<UnitTest>(); - unitTests.add(new UT_primitives(this, mRes)); - unitTests.add(new UT_rsdebug(this, mRes)); - unitTests.add(new UT_rstypes(this, mRes)); - unitTests.add(new UT_vector_array(this, mRes)); - unitTests.add(new UT_fp_mad(this, mRes)); + unitTests.add(new UT_primitives(this, mRes, mCtx)); + unitTests.add(new UT_rsdebug(this, mRes, mCtx)); + unitTests.add(new UT_rstypes(this, mRes, mCtx)); + unitTests.add(new UT_fp_mad(this, mRes, mCtx)); /* unitTests.add(new UnitTest(null, "<Pass>", 1)); unitTests.add(new UnitTest()); diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java index 2f7542d..368f286 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java +++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java @@ -41,8 +41,11 @@ import android.view.MotionEvent; public class RSTestView extends RSSurfaceView { + private Context mCtx; + public RSTestView(Context context) { super(context); + mCtx = context; //setFocusable(true); } @@ -55,7 +58,7 @@ public class RSTestView extends RSSurfaceView { RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); mRS = createRenderScriptGL(sc); mRS.setSurface(holder, w, h); - mRender = new RSTestCore(); + mRender = new RSTestCore(mCtx); mRender.init(mRS, getResources(), w, h); } } @@ -92,5 +95,3 @@ public class RSTestView extends RSSurfaceView { return ret; } } - - diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java index 409192b..f2c91af 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java +++ b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java @@ -16,19 +16,20 @@ package com.android.rs.test; +import android.content.Context; import android.content.res.Resources; import android.renderscript.*; public class UT_fp_mad extends UnitTest { private Resources mRes; - protected UT_fp_mad(RSTestCore rstc, Resources res) { - super(rstc, "Fp_Mad"); + protected UT_fp_mad(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Fp_Mad", ctx); mRes = res; } public void run() { - RenderScript pRS = RenderScript.create(); + RenderScript pRS = RenderScript.create(mCtx); ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad); pRS.setMessageHandler(mRsMessage); s.invoke_fp_mad_test(0, 0); @@ -37,4 +38,3 @@ public class UT_fp_mad extends UnitTest { pRS.destroy(); } } - diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java index 6e0859a..b7a65a5 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java +++ b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java @@ -16,14 +16,15 @@ package com.android.rs.test; +import android.content.Context; import android.content.res.Resources; import android.renderscript.*; public class UT_primitives extends UnitTest { private Resources mRes; - protected UT_primitives(RSTestCore rstc, Resources res) { - super(rstc, "Primitives"); + protected UT_primitives(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Primitives", ctx); mRes = res; } @@ -87,7 +88,7 @@ public class UT_primitives extends UnitTest { } public void run() { - RenderScript pRS = RenderScript.create(); + RenderScript pRS = RenderScript.create(mCtx); ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives); pRS.setMessageHandler(mRsMessage); if (!initializeGlobals(s)) { @@ -101,4 +102,3 @@ public class UT_primitives extends UnitTest { pRS.destroy(); } } - diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java b/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java index df31f98..0614b1a 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java +++ b/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java @@ -16,19 +16,20 @@ package com.android.rs.test; +import android.content.Context; import android.content.res.Resources; import android.renderscript.*; public class UT_rsdebug extends UnitTest { private Resources mRes; - protected UT_rsdebug(RSTestCore rstc, Resources res) { - super(rstc, "rsDebug"); + protected UT_rsdebug(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsDebug", ctx); mRes = res; } public void run() { - RenderScript pRS = RenderScript.create(); + RenderScript pRS = RenderScript.create(mCtx); ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug); pRS.setMessageHandler(mRsMessage); s.invoke_test_rsdebug(0, 0); @@ -37,4 +38,3 @@ public class UT_rsdebug extends UnitTest { pRS.destroy(); } } - diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java b/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java index d1232ce..74211c8 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java +++ b/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java @@ -16,19 +16,20 @@ package com.android.rs.test; +import android.content.Context; import android.content.res.Resources; import android.renderscript.*; public class UT_rstypes extends UnitTest { private Resources mRes; - protected UT_rstypes(RSTestCore rstc, Resources res) { - super(rstc, "rsTypes"); + protected UT_rstypes(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsTypes", ctx); mRes = res; } public void run() { - RenderScript pRS = RenderScript.create(); + RenderScript pRS = RenderScript.create(mCtx); ScriptC_rstypes s = new ScriptC_rstypes(pRS, mRes, R.raw.rstypes); pRS.setMessageHandler(mRsMessage); s.invoke_test_rstypes(0, 0); @@ -37,4 +38,3 @@ public class UT_rstypes extends UnitTest { pRS.destroy(); } } - diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_vector_array.java b/libs/rs/java/tests/src/com/android/rs/test/UT_vector_array.java deleted file mode 100644 index 6798781..0000000 --- a/libs/rs/java/tests/src/com/android/rs/test/UT_vector_array.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010 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.rs.test; - -import android.content.res.Resources; -import android.renderscript.*; - -public class UT_vector_array extends UnitTest { - private Resources mRes; - - protected UT_vector_array(RSTestCore rstc, Resources res) { - super(rstc, "Vector Array"); - mRes = res; - } - - public void run() { - RenderScript pRS = RenderScript.create(); - ScriptC_vector_array s = new ScriptC_vector_array(pRS, mRes, R.raw.vector_array); - pRS.setMessageHandler(mRsMessage); - s.invoke_vector_array_test(); - pRS.finish(); - waitForMessage(); - pRS.destroy(); - } -} - diff --git a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java index 8923a19..a7722c7 100644 --- a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java +++ b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java @@ -15,6 +15,7 @@ */ package com.android.rs.test; +import android.content.Context; import android.renderscript.RenderScript.RSMessageHandler; import android.util.Log; @@ -24,6 +25,7 @@ public class UnitTest extends Thread { private ScriptField_ListAllocs_s.Item mItem; private RSTestCore mRSTC; private boolean msgHandled; + protected Context mCtx; /* These constants must match those in shared.rsh */ public static final int RS_MSG_TEST_PASSED = 100; @@ -32,25 +34,26 @@ public class UnitTest extends Thread { private static int numTests = 0; public int testID; - protected UnitTest(RSTestCore rstc, String n, int initResult) { + protected UnitTest(RSTestCore rstc, String n, int initResult, Context ctx) { super(); mRSTC = rstc; name = n; msgHandled = false; + mCtx = ctx; result = initResult; testID = numTests++; } - protected UnitTest(RSTestCore rstc, String n) { - this(rstc, n, 0); + protected UnitTest(RSTestCore rstc, String n, Context ctx) { + this(rstc, n, 0, ctx); } - protected UnitTest(RSTestCore rstc) { - this (rstc, "<Unknown>"); + protected UnitTest(RSTestCore rstc, Context ctx) { + this (rstc, "<Unknown>", ctx); } - protected UnitTest() { - this (null); + protected UnitTest(Context ctx) { + this (null, ctx); } protected RSMessageHandler mRsMessage = new RSMessageHandler() { @@ -101,4 +104,3 @@ public class UnitTest extends Thread { } } } - diff --git a/libs/rs/java/tests/src/com/android/rs/test/vector_array.rs b/libs/rs/java/tests/src/com/android/rs/test/vector_array.rs deleted file mode 100644 index 49e38c1..0000000 --- a/libs/rs/java/tests/src/com/android/rs/test/vector_array.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2009 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 "shared.rsh" - -typedef struct float3Struct{ - float3 arr[2]; -} float3Struct; - -float3Struct f; - -bool size_test() { - bool failed = false; - int expectedSize = 2 * 3 * (int) sizeof(float); - int actualSize = (int) sizeof(f); - - rsDebug("Size of struct { float3 arr[2]; } (expected):", expectedSize); - rsDebug("Size of struct { float3 arr[2]; } (actual) :", actualSize); - - if (expectedSize != actualSize) { - failed = true; - } - - return failed; -} - -void vector_array_test() { - bool failed = false; - failed |= size_test(); - - if (failed) { - rsSendToClientBlocking(RS_MSG_TEST_FAILED); - } - else { - rsSendToClientBlocking(RS_MSG_TEST_PASSED); - } -} - diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index 97ecca0..5daba08 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -77,18 +77,16 @@ ElementCreate2 { ret RsElement } -AllocationUpdateFromBitmap { +AllocationCopyFromBitmap { param RsAllocation alloc - param RsElement srcFmt param const void * data + param size_t dataLen } -AllocationCreateBitmapRef { - param RsType type - param RsAsyncVoidPtr bmpPtr - param RsAsyncVoidPtr callbackData - param RsBitmapCallback_t callback - ret RsAllocation +AllocationCopyToBitmap { + param RsAllocation alloc + param void * data + param size_t dataLen } AllocationUploadToTexture { @@ -324,6 +322,7 @@ ScriptCSetText { ScriptCCreate { param const char * resName + param const char * cacheDir ret RsScript } diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index f42be0e..78b570a 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -36,7 +36,7 @@ Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages) : Object mUsageFlags = usages; - mPtr = malloc(mType->getSizeBytes()); + allocScriptMemory(); if (mType->getElement()->getHasReferences()) { memset(mPtr, 0, mType->getSizeBytes()); } @@ -45,17 +45,6 @@ Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages) : Object } } -Allocation::Allocation(Context *rsc, const Type *type, void *bmp, - void *callbackData, RsBitmapCallback_t callback) - : ObjectBase(rsc) { - init(rsc, type); - - mUsageFlags = RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; - - mPtr = bmp; - mUserBitmapCallback = callback; - mUserBitmapCallbackData = callbackData; -} void Allocation::init(Context *rsc, const Type *type) { mPtr = NULL; @@ -67,10 +56,10 @@ void Allocation::init(Context *rsc, const Type *type) { mReadWriteRatio = 0; mUpdateSize = 0; + mUsageFlags = 0; + mMipmapControl = RS_ALLOCATION_MIPMAP_NONE; - mIsTexture = false; mTextureID = 0; - mIsVertexBuffer = false; mBufferID = 0; mUploadDefered = false; @@ -86,10 +75,9 @@ void Allocation::init(Context *rsc, const Type *type) { Allocation::~Allocation() { if (mUserBitmapCallback != NULL) { mUserBitmapCallback(mUserBitmapCallbackData); - } else { - free(mPtr); + mPtr = NULL; } - mPtr = NULL; + freeScriptMemory(); if (mBufferID) { // Causes a SW crash.... @@ -119,35 +107,46 @@ bool Allocation::fixAllocation() { return false; } -void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset) { - rsAssert(lodOffset < mType->getLODCount()); - mIsTexture = true; - mTextureLOD = lodOffset; +void Allocation::deferedUploadToTexture(const Context *rsc) { + mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; mUploadDefered = true; - mTextureGenMipmap = !mType->getDimLOD() && genMipmap; } uint32_t Allocation::getGLTarget() const { - if (mIsTexture) { + if (getIsTexture()) { if (mType->getDimFaces()) { return GL_TEXTURE_CUBE_MAP; } else { return GL_TEXTURE_2D; } } - if (mIsVertexBuffer) { + if (getIsBufferObject()) { return GL_ARRAY_BUFFER; } return 0; } +void Allocation::allocScriptMemory() { + rsAssert(!mPtr); + mPtr = malloc(mType->getSizeBytes()); +} + +void Allocation::freeScriptMemory() { + rsAssert(!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)); + if (mPtr) { + free(mPtr); + mPtr = NULL; + } +} + + void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT); - if (mIsTexture) { + if (getIsTexture()) { uploadToTexture(rsc); } - if (mIsVertexBuffer) { + if (getIsBufferObject()) { uploadToBufferObject(rsc); } @@ -156,7 +155,7 @@ void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { void Allocation::uploadToTexture(const Context *rsc) { - mIsTexture = true; + mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; GLenum type = mType->getElement()->getComponent().getGLType(); GLenum format = mType->getElement()->getComponent().getGLFormat(); @@ -164,6 +163,10 @@ void Allocation::uploadToTexture(const Context *rsc) { return; } + if (!mPtr) { + return; + } + bool isFirstUpload = false; if (!mTextureID) { @@ -182,41 +185,46 @@ void Allocation::uploadToTexture(const Context *rsc) { } GLenum target = (GLenum)getGLTarget(); - glBindTexture(target, mTextureID); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - if (target == GL_TEXTURE_2D) { - upload2DTexture(isFirstUpload); + upload2DTexture(isFirstUpload, mPtr); } else if (target == GL_TEXTURE_CUBE_MAP) { uploadCubeTexture(isFirstUpload); } - if (mTextureGenMipmap) { + if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) { #ifndef ANDROID_RS_BUILD_FOR_HOST glGenerateMipmap(target); #endif //ANDROID_RS_BUILD_FOR_HOST } + + if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { + freeScriptMemory(); + } + rsc->checkError("Allocation::uploadToTexture"); } -void Allocation::upload2DTexture(bool isFirstUpload) { +void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) { GLenum type = mType->getElement()->getComponent().getGLType(); GLenum format = mType->getElement()->getComponent().getGLFormat(); - Adapter2D adapt(getContext(), this); - for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) { - adapt.setLOD(lod+mTextureLOD); + GLenum target = (GLenum)getGLTarget(); + glBindTexture(target, mTextureID); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) { + const uint8_t *p = (const uint8_t *)ptr; + p += mType->getLODOffset(lod); - uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); if (isFirstUpload) { glTexImage2D(GL_TEXTURE_2D, lod, format, - adapt.getDimX(), adapt.getDimY(), - 0, format, type, ptr); + mType->getLODDimX(lod), mType->getLODDimY(lod), + 0, format, type, p); } else { glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0, - adapt.getDimX(), adapt.getDimY(), - format, type, ptr); + mType->getLODDimX(lod), mType->getLODDimY(lod), + format, type, p); } } } @@ -225,6 +233,10 @@ void Allocation::uploadCubeTexture(bool isFirstUpload) { GLenum type = mType->getElement()->getComponent().getGLType(); GLenum format = mType->getElement()->getComponent().getGLFormat(); + GLenum target = (GLenum)getGLTarget(); + glBindTexture(target, mTextureID); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + GLenum faceOrder[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, @@ -238,8 +250,8 @@ void Allocation::uploadCubeTexture(bool isFirstUpload) { for (uint32_t face = 0; face < 6; face ++) { adapt.setFace(face); - for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) { - adapt.setLOD(lod+mTextureLOD); + for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) { + adapt.setLOD(lod); uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); @@ -257,7 +269,7 @@ void Allocation::uploadCubeTexture(bool isFirstUpload) { } void Allocation::deferedUploadToBufferObject(const Context *rsc) { - mIsVertexBuffer = true; + mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX; mUploadDefered = true; } @@ -265,7 +277,7 @@ void Allocation::uploadToBufferObject(const Context *rsc) { rsAssert(!mType->getDimY()); rsAssert(!mType->getDimZ()); - mIsVertexBuffer = true; + mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX; if (!mBufferID) { glGenBuffers(1, &mBufferID); @@ -470,8 +482,8 @@ void Allocation::dumpLOGV(const char *prefix) const { LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i", prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead); - LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i", - prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID); + LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i", + prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID); } void Allocation::serialize(OStream *stream) const { @@ -517,7 +529,7 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) { return NULL; } - Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_ALL); + Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT); alloc->setName(name.string(), name.size()); // Read in all of our allocation data @@ -596,7 +608,7 @@ namespace renderscript { void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) { Allocation *alloc = static_cast<Allocation *>(va); - alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel); + alloc->deferedUploadToTexture(rsc); } void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) { @@ -672,81 +684,6 @@ static void mip(const Adapter2D &out, const Adapter2D &in) { } } -typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count); - -static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count) { - memcpy(dst, src, count * 2); -} -static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count) { - memcpy(dst, src, count); -} -static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count) { - memcpy(dst, src, count * 4); -} - -static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count) { - uint16_t *d = static_cast<uint16_t *>(dst); - const uint8_t *s = static_cast<const uint8_t *>(src); - - while (count--) { - *d = rs888to565(s[0], s[1], s[2]); - d++; - s+= 3; - } -} - -static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count) { - uint16_t *d = static_cast<uint16_t *>(dst); - const uint8_t *s = static_cast<const uint8_t *>(src); - - while (count--) { - *d = rs888to565(s[0], s[1], s[2]); - d++; - s+= 4; - } -} - -static ElementConverter_t pickConverter(const Element *dst, const Element *src) { - GLenum srcGLType = src->getComponent().getGLType(); - GLenum srcGLFmt = src->getComponent().getGLFormat(); - GLenum dstGLType = dst->getComponent().getGLType(); - GLenum dstGLFmt = dst->getComponent().getGLFormat(); - - if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) { - switch (dst->getSizeBytes()) { - case 4: - return elementConverter_cpy_32; - case 2: - return elementConverter_cpy_16; - case 1: - return elementConverter_cpy_8; - } - } - - if (srcGLType == GL_UNSIGNED_BYTE && - srcGLFmt == GL_RGB && - dstGLType == GL_UNSIGNED_SHORT_5_6_5 && - dstGLFmt == GL_RGB) { - - return elementConverter_888_to_565; - } - - if (srcGLType == GL_UNSIGNED_BYTE && - srcGLFmt == GL_RGBA && - dstGLType == GL_UNSIGNED_SHORT_5_6_5 && - dstGLFmt == GL_RGB) { - - return elementConverter_8888_to_565; - } - - LOGE("pickConverter, unsuported combo, src %p, dst %p", src, dst); - LOGE("pickConverter, srcGLType = %x, srcGLFmt = %x", srcGLType, srcGLFmt); - LOGE("pickConverter, dstGLType = %x, dstGLFmt = %x", dstGLType, dstGLFmt); - src->dumpLOGV("SRC "); - dst->dumpLOGV("DST "); - return 0; -} - #ifndef ANDROID_RS_BUILD_FOR_HOST void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) { @@ -754,27 +691,21 @@ void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType a->syncAll(rsc, src); } -RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype, - void *bmp, void *callbackData, - RsBitmapCallback_t callback) { - const Type * type = static_cast<const Type *>(vtype); - Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback); - alloc->incUserRef(); - return alloc; -} - -void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, - RsElement _src, const void *data) { +void rsi_AllocationCopyFromBitmap(Context *rsc, RsAllocation va, const void *data, size_t dataLen) { Allocation *texAlloc = static_cast<Allocation *>(va); - const Element *src = static_cast<const Element *>(_src); - const Element *dst = texAlloc->getType()->getElement(); - uint32_t w = texAlloc->getType()->getDimX(); - uint32_t h = texAlloc->getType()->getDimY(); - bool genMips = texAlloc->getType()->getDimLOD(); - - ElementConverter_t cvt = pickConverter(dst, src); - if (cvt) { - cvt(texAlloc->getPtr(), data, w * h); + const Type * t = texAlloc->getType(); + + uint32_t w = t->getDimX(); + uint32_t h = t->getDimY(); + bool genMips = t->getDimLOD(); + size_t s = w * h * t->getElementSizeBytes(); + if (s != dataLen) { + rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size"); + return; + } + + if (texAlloc->getIsScript()) { + memcpy(texAlloc->getPtr(), data, s); if (genMips) { Adapter2D adapt(rsc, texAlloc); Adapter2D adapt2(rsc, texAlloc); @@ -785,8 +716,22 @@ void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, } } } else { - rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format"); + texAlloc->upload2DTexture(false, data); } + +} + +void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) { + Allocation *texAlloc = static_cast<Allocation *>(va); + const Type * t = texAlloc->getType(); + + size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes(); + if (s != dataLen) { + rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size"); + return; + } + + memcpy(data, texAlloc->getPtr(), s); } void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) { @@ -842,7 +787,7 @@ const void * rsaAllocationGetType(RsContext con, RsAllocation va) { } RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype, - RsAllocationMipmapGenerationControl mips, + RsAllocationMipmapControl mips, uint32_t usages) { Context *rsc = static_cast<Context *>(con); Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages); @@ -852,7 +797,7 @@ RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype, RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype, - RsAllocationMipmapGenerationControl mips, + RsAllocationMipmapControl mips, const void *data, uint32_t usages) { Context *rsc = static_cast<Context *>(con); Type *t = static_cast<Type *>(vtype); @@ -865,7 +810,7 @@ RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype, } memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes()); - if (mips == RS_MIPMAP_FULL) { + if (mips == RS_ALLOCATION_MIPMAP_FULL) { Adapter2D adapt(rsc, texAlloc); Adapter2D adapt2(rsc, texAlloc); for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) { @@ -875,11 +820,12 @@ RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype, } } + texAlloc->deferedUploadToTexture(rsc); return texAlloc; } RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype, - RsAllocationMipmapGenerationControl mips, + RsAllocationMipmapControl mips, const void *data, uint32_t usages) { Context *rsc = static_cast<Context *>(con); Type *t = static_cast<Type *>(vtype); @@ -905,7 +851,7 @@ RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype, // Move the data pointer to the next cube face sourcePtr += cpySize; - if (mips == RS_MIPMAP_FULL) { + if (mips == RS_ALLOCATION_MIPMAP_FULL) { Adapter2D adapt(rsc, texAlloc); Adapter2D adapt2(rsc, texAlloc); adapt.setFace(face); @@ -918,5 +864,6 @@ RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype, } } + texAlloc->deferedUploadToTexture(rsc); return texAlloc; } diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index e63c7ab..4a5f3da 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -30,7 +30,6 @@ class Allocation : public ObjectBase { public: Allocation(Context *rsc, const Type *, uint32_t usages); - Allocation(Context *rsc, const Type *, void *bmp, void *callbackData, RsBitmapCallback_t callback); virtual ~Allocation(); @@ -46,7 +45,7 @@ public: void syncAll(Context *rsc, RsAllocationUsageType src); - void deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset); + void deferedUploadToTexture(const Context *rsc); void uploadToTexture(const Context *rsc); uint32_t getTextureID() const {return mTextureID;} @@ -88,14 +87,25 @@ public: virtual void uploadCheck(Context *rsc); - bool getIsTexture() const {return mIsTexture;} - bool getIsBufferObject() const {return mIsVertexBuffer;} + bool getIsScript() const { + return (mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0; + } + bool getIsTexture() const { + return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0; + } + bool getIsBufferObject() const { + return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0; + } 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; - bool getHasGraphicsMipmaps() const {return mTextureGenMipmap;} + bool getHasGraphicsMipmaps() const { + return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE; + } + + void upload2DTexture(bool isFirstUpload, const void *ptr); protected: ObjectBaseRef<const Type> mType; @@ -115,6 +125,7 @@ protected: bool mGpuRead; uint32_t mUsageFlags; + RsAllocationMipmapControl mMipmapControl; // more usage hint data from the application // which can be used by a driver to pick the best memory type. @@ -125,23 +136,22 @@ protected: // Is this a legal structure to be used as a texture source. // Initially this will require 1D or 2D and color data - bool mIsTexture; - bool mTextureGenMipmap; - uint32_t mTextureLOD; 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. - bool mIsVertexBuffer; uint32_t mBufferID; bool mUploadDefered; private: void init(Context *rsc, const Type *); - void upload2DTexture(bool isFirstUpload); void uploadCubeTexture(bool isFirstUpload); + + void allocScriptMemory(); + void freeScriptMemory(); + }; } diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 1dc9540..49ee676 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -207,6 +207,7 @@ public: uint32_t getMaxFragmentTextures() const {return mGL.mMaxFragmentTextureImageUnits;} uint32_t getMaxFragmentUniformVectors() const {return mGL.mMaxFragmentUniformVectors;} uint32_t getMaxVertexUniformVectors() const {return mGL.mMaxVertexUniformVectors;} + uint32_t getMaxVertexAttributes() const {return mGL.mMaxVertexAttribs;} void launchThreads(WorkerCallback_t cbk, void *data); uint32_t getWorkerPoolSize() const {return (uint32_t)mWorkers.mCount;} diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 3d17be2..3f9a9d6 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -463,7 +463,7 @@ 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->deferedUploadToTexture(mRSC, false, 0); + mTextTexture->deferedUploadToTexture(mRSC); mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get()); // Some debug code @@ -529,7 +529,7 @@ void FontState::initTextTexture() { Allocation *cacheAlloc = new Allocation(mRSC, texType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE); mTextTexture.set(cacheAlloc); - mTextTexture->deferedUploadToTexture(mRSC, false, 0); + mTextTexture->deferedUploadToTexture(mRSC); // Split up our cache texture into lines of certain widths int32_t nextLine = 0; diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index d4edafd..507430d 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -47,7 +47,6 @@ ScriptC::~ScriptC() { } void ScriptC::setupScript(Context *rsc) { - setupGLState(rsc); mEnviroment.mStartTimeMillis = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); @@ -123,6 +122,7 @@ uint32_t ScriptC::run(Context *rsc) { return 0; } + setupGLState(rsc); setupScript(rsc); uint32_t ret = 0; @@ -278,6 +278,7 @@ void ScriptC::runForEach(Context *rsc, rsAssert(ain->getType()->getDimZ() == 0); + setupGLState(rsc); setupScript(rsc); Script * oldTLS = setTLS(this); @@ -336,7 +337,6 @@ void ScriptC::runForEach(Context *rsc, } void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len) { - //LOGE("rsi_ScriptInvoke %i", slot); if ((slot >= mEnviroment.mInvokeFunctionCount) || (mEnviroment.mInvokeFunctions[slot] == NULL)) { rsc->setError(RS_ERROR_BAD_SCRIPT, "Calling invoke on bad script"); @@ -402,7 +402,7 @@ static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name) { extern const char rs_runtime_lib_bc[]; extern unsigned rs_runtime_lib_bc_size; -void ScriptCState::runCompiler(Context *rsc, ScriptC *s, const char *resName) { +void ScriptCState::runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir) { { s->mBccScript = bccCreateScript(); s->mEnviroment.mIsThreadable = true; @@ -413,7 +413,8 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s, const char *resName) { if (bccReadBC(s->mBccScript, s->mEnviroment.mScriptText, s->mEnviroment.mScriptTextLength, - resName) >= 0) { + resName, + cacheDir) >= 0) { //bccLinkBC(s->mBccScript, rs_runtime_lib_bc, rs_runtime_lib_bc_size); bccCompileBC(s->mBccScript); } else { @@ -534,7 +535,7 @@ void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) { ss->mScript->mEnviroment.mScriptTextLength = len; } -RsScript rsi_ScriptCCreate(Context * rsc, const char *resName) +RsScript rsi_ScriptCCreate(Context * rsc, const char *resName, const char *cacheDir) { ScriptCState *ss = &rsc->mScriptC; @@ -542,7 +543,7 @@ RsScript rsi_ScriptCCreate(Context * rsc, const char *resName) ss->mScript.clear(); s->incUserRef(); - ss->runCompiler(rsc, s.get(), resName); + ss->runCompiler(rsc, s.get(), resName, cacheDir); ss->clear(rsc); return s.get(); } diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h index ab2db5c8..a714132 100644 --- a/libs/rs/rsScriptC.h +++ b/libs/rs/rsScriptC.h @@ -83,7 +83,7 @@ public: void init(Context *rsc); void clear(Context *rsc); - void runCompiler(Context *rsc, ScriptC *s, const char *resName); + void runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir); struct SymbolTable_t { const char * mName; diff --git a/libs/rs/rsVertexArray.cpp b/libs/rs/rsVertexArray.cpp index 8a9fafe..d9393fe 100644 --- a/libs/rs/rsVertexArray.cpp +++ b/libs/rs/rsVertexArray.cpp @@ -81,8 +81,12 @@ void VertexArray::setupGL2(const Context *rsc, class VertexArrayState *state, ShaderCache *sc) const { rsc->checkError("VertexArray::setupGL2 start"); - for (uint32_t ct=1; ct <= state->mLastEnableCount; ct++) { - glDisableVertexAttribArray(ct); + uint32_t maxAttrs = state->mAttrsEnabledSize; + for (uint32_t ct=1; ct < maxAttrs; ct++) { + if(state->mAttrsEnabled[ct]) { + glDisableVertexAttribArray(ct); + state->mAttrsEnabled[ct] = false; + } } rsc->checkError("VertexArray::setupGL2 disabled"); @@ -91,10 +95,11 @@ void VertexArray::setupGL2(const Context *rsc, if (rsc->props.mLogShadersAttr) { logAttrib(ct, slot); } - if (slot < 0) { + if (slot < 0 || slot >= (int32_t)maxAttrs) { continue; } glEnableVertexAttribArray(slot); + state->mAttrsEnabled[slot] = true; glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); glVertexAttribPointer(slot, mAttribs[ct].size, @@ -103,12 +108,25 @@ void VertexArray::setupGL2(const Context *rsc, mAttribs[ct].stride, mAttribs[ct].ptr + mAttribs[ct].offset); } - state->mLastEnableCount = mCount; rsc->checkError("VertexArray::setupGL2 done"); } //////////////////////////////////////////// +VertexArrayState::VertexArrayState() { + mAttrsEnabled = NULL; + mAttrsEnabledSize = 0; +} -void VertexArrayState::init(Context *) { - mLastEnableCount = 0; +VertexArrayState::~VertexArrayState() { + if (mAttrsEnabled) { + delete[] mAttrsEnabled; + mAttrsEnabled = NULL; + } +} +void VertexArrayState::init(Context *rsc) { + mAttrsEnabledSize = rsc->getMaxVertexAttributes(); + mAttrsEnabled = new bool[mAttrsEnabledSize]; + for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) { + mAttrsEnabled[ct] = false; + } } diff --git a/libs/rs/rsVertexArray.h b/libs/rs/rsVertexArray.h index 7bcfa68..45d9e82 100644 --- a/libs/rs/rsVertexArray.h +++ b/libs/rs/rsVertexArray.h @@ -63,9 +63,12 @@ protected: class VertexArrayState { public: + VertexArrayState(); + ~VertexArrayState(); void init(Context *); - uint32_t mLastEnableCount; + bool *mAttrsEnabled; + uint32_t mAttrsEnabledSize; }; diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp index 969ee79..b8a7a79 100644 --- a/libs/surfaceflinger_client/ISurfaceComposer.cpp +++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp @@ -127,13 +127,16 @@ public: virtual status_t captureScreen(DisplayID dpy, sp<IMemoryHeap>* heap, uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight) + uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInt32(dpy); data.writeInt32(reqWidth); data.writeInt32(reqHeight); + data.writeInt32(minLayerZ); + data.writeInt32(maxLayerZ); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder()); *width = reply.readInt32(); @@ -231,11 +234,13 @@ status_t BnSurfaceComposer::onTransact( DisplayID dpy = data.readInt32(); uint32_t reqWidth = data.readInt32(); uint32_t reqHeight = data.readInt32(); + uint32_t minLayerZ = data.readInt32(); + uint32_t maxLayerZ = data.readInt32(); sp<IMemoryHeap> heap; uint32_t w, h; PixelFormat f; status_t res = captureScreen(dpy, &heap, &w, &h, &f, - reqWidth, reqHeight); + reqWidth, reqHeight, minLayerZ, maxLayerZ); reply->writeStrongBinder(heap->asBinder()); reply->writeInt32(w); reply->writeInt32(h); diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp index f270461..d336724 100644 --- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp @@ -555,7 +555,8 @@ status_t ScreenshotClient::update() { if (s == NULL) return NO_INIT; mHeap = 0; return s->captureScreen(0, &mHeap, - &mWidth, &mHeight, &mFormat, 0, 0); + &mWidth, &mHeight, &mFormat, 0, 0, + 0, -1UL); } status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) { @@ -563,7 +564,18 @@ status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) { if (s == NULL) return NO_INIT; mHeap = 0; return s->captureScreen(0, &mHeap, - &mWidth, &mHeight, &mFormat, reqWidth, reqHeight); + &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, + 0, -1UL); +} + +status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ) { + sp<ISurfaceComposer> s(ComposerService::getComposerService()); + if (s == NULL) return NO_INIT; + mHeap = 0; + return s->captureScreen(0, &mHeap, + &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, + minLayerZ, maxLayerZ); } void ScreenshotClient::release() { diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 1f6a920..ed0cb8e 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -908,9 +908,11 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout ssize_t connectionIndex = getConnectionIndexLocked(inputChannel); if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); - synthesizeCancelationEventsForConnectionLocked( - connection, InputState::CANCEL_ALL_EVENTS, - "application not responding"); + if (connection->status == Connection::STATUS_NORMAL) { + synthesizeCancelationEventsForConnectionLocked( + connection, InputState::CANCEL_ALL_EVENTS, + "application not responding"); + } } } } @@ -3056,7 +3058,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( // the original UP in which case we would not generate the fallback UP. synthesizeCancelationEventsForConnectionLocked(connection, InputState::CANCEL_FALLBACK_EVENTS, - "Application handled a non-fallback event."); + "application handled a non-fallback event, canceling all fallback events"); } else { // If the application did not handle a non-fallback key, then ask // the policy what to do with it. We might generate a fallback key @@ -3071,6 +3073,12 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( mLock.lock(); + if (connection->status != Connection::STATUS_NORMAL) { + return; + } + + assert(connection->outboundQueue.headSentinel.next == dispatchEntry); + if (fallback) { // Restart the dispatch cycle using the fallback key. keyEntry->eventTime = event.getEventTime(); |
