diff options
Diffstat (limited to 'libs')
25 files changed, 548 insertions, 301 deletions
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index ee90702..ce85d46 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -22,6 +22,62 @@ namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// +// Defines +/////////////////////////////////////////////////////////////////////////////// + +#define PATH_HEAP_SIZE 64 + +/////////////////////////////////////////////////////////////////////////////// +// Helpers +/////////////////////////////////////////////////////////////////////////////// + +PathHeap::PathHeap(): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) { +} + +PathHeap::PathHeap(SkFlattenableReadBuffer& buffer): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) { + int count = buffer.readS32(); + + mPaths.setCount(count); + SkPath** ptr = mPaths.begin(); + SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath)); + + for (int i = 0; i < count; i++) { + new (p) SkPath; + p->unflatten(buffer); + *ptr++ = p; + p++; + } +} + +PathHeap::~PathHeap() { + SkPath** iter = mPaths.begin(); + SkPath** stop = mPaths.end(); + while (iter < stop) { + (*iter)->~SkPath(); + iter++; + } +} + +int PathHeap::append(const SkPath& path) { + SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath)); + new (p) SkPath(path); + *mPaths.append() = p; + return mPaths.count(); +} + +void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const { + int count = mPaths.count(); + + buffer.write32(count); + SkPath** iter = mPaths.begin(); + SkPath** stop = mPaths.end(); + while (iter < stop) { + (*iter)->flatten(buffer); + iter++; + } +} + +/////////////////////////////////////////////////////////////////////////////// // Display list /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 735f0e7..5d02bd7 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -45,39 +45,11 @@ namespace uirenderer { class PathHeap: public SkRefCnt { public: - PathHeap(): mHeap(64 * sizeof(SkPath)) { - }; - - PathHeap(SkFlattenableReadBuffer& buffer): mHeap(64 * sizeof(SkPath)) { - int count = buffer.readS32(); - - mPaths.setCount(count); - SkPath** ptr = mPaths.begin(); - SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath)); - - for (int i = 0; i < count; i++) { - new (p) SkPath; - p->unflatten(buffer); - *ptr++ = p; - p++; - } - } + PathHeap(); + PathHeap(SkFlattenableReadBuffer& buffer); + ~PathHeap(); - ~PathHeap() { - SkPath** iter = mPaths.begin(); - SkPath** stop = mPaths.end(); - while (iter < stop) { - (*iter)->~SkPath(); - iter++; - } - } - - int append(const SkPath& path) { - SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath)); - new (p) SkPath(path); - *mPaths.append() = p; - return mPaths.count(); - } + int append(const SkPath& path); int count() const { return mPaths.count(); } @@ -85,17 +57,7 @@ public: return *mPaths[index]; } - void flatten(SkFlattenableWriteBuffer& buffer) const { - int count = mPaths.count(); - - buffer.write32(count); - SkPath** iter = mPaths.begin(); - SkPath** stop = mPaths.end(); - while (iter < stop) { - (*iter)->flatten(buffer); - iter++; - } - } + void flatten(SkFlattenableWriteBuffer& buffer) const; private: SkChunkAlloc mHeap; diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index b66696d..4e4a277 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -435,25 +435,25 @@ void FontRenderer::initTextTexture() { glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Split up our cache texture into lines of certain widths int nextLine = 0; - mCacheLines.push(new CacheTextureLine(mCacheWidth, 16, nextLine, 0)); + mCacheLines.push(new CacheTextureLine(mCacheWidth, 18, nextLine, 0)); nextLine += mCacheLines.top()->mMaxHeight; - mCacheLines.push(new CacheTextureLine(mCacheWidth, 24, nextLine, 0)); + mCacheLines.push(new CacheTextureLine(mCacheWidth, 26, nextLine, 0)); nextLine += mCacheLines.top()->mMaxHeight; - mCacheLines.push(new CacheTextureLine(mCacheWidth, 24, nextLine, 0)); + mCacheLines.push(new CacheTextureLine(mCacheWidth, 26, nextLine, 0)); nextLine += mCacheLines.top()->mMaxHeight; - mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0)); + mCacheLines.push(new CacheTextureLine(mCacheWidth, 34, nextLine, 0)); nextLine += mCacheLines.top()->mMaxHeight; - mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0)); + mCacheLines.push(new CacheTextureLine(mCacheWidth, 34, nextLine, 0)); nextLine += mCacheLines.top()->mMaxHeight; - mCacheLines.push(new CacheTextureLine(mCacheWidth, 40, nextLine, 0)); + mCacheLines.push(new CacheTextureLine(mCacheWidth, 42, nextLine, 0)); nextLine += mCacheLines.top()->mMaxHeight; mCacheLines.push(new CacheTextureLine(mCacheWidth, mCacheHeight - nextLine, nextLine, 0)); } @@ -631,6 +631,7 @@ void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) { precacheLatin(paint); } } + FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) { checkInit(); @@ -713,7 +714,7 @@ void FontRenderer::computeGaussianWeights(float* weights, int32_t radius) { float normalizeFactor = 0.0f; for(int32_t r = -radius; r <= radius; r ++) { - float floatR = (float)r; + float floatR = (float) r; weights[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2); normalizeFactor += weights[r + radius]; } @@ -742,7 +743,7 @@ void FontRenderer::horizontalBlur(float* weights, int32_t radius, if ((x > radius) && (x < (width - radius))) { const uint8_t *i = input + (x - radius); for(int r = -radius; r <= radius; r ++) { - currentPixel = (float)(*i); + currentPixel = (float) (*i); blurredPixel += currentPixel * gPtr[0]; gPtr++; i++; diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index de5c019..4fb8f8d 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -183,14 +183,14 @@ protected: } bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) { - if (glyph.fHeight > mMaxHeight) { + if (glyph.fHeight + 2 > mMaxHeight) { return false; } - if (mCurrentCol + glyph.fWidth < mMaxWidth) { - *retOriginX = mCurrentCol; - *retOriginY = mCurrentRow; - mCurrentCol += glyph.fWidth; + if (mCurrentCol + glyph.fWidth + 2 < mMaxWidth) { + *retOriginX = mCurrentCol + 1; + *retOriginY = mCurrentRow + 1; + mCurrentCol += glyph.fWidth + 2; mDirty = true; return true; } diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 60523db..a0cc5d6 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -44,7 +44,7 @@ struct LayerSize { uint32_t id; bool operator<(const LayerSize& rhs) const { - if (id != 0 && rhs.id != 0) { + if (id != 0 && rhs.id != 0 && id != rhs.id) { return id < rhs.id; } if (width == rhs.width) { @@ -54,7 +54,7 @@ struct LayerSize { } bool operator==(const LayerSize& rhs) const { - return width == rhs.width && height == rhs.height; + return id == rhs.id && width == rhs.width && height == rhs.height; } }; // struct LayerSize @@ -83,7 +83,7 @@ struct Layer { */ bool blend; /** - * Indicates that this layer has never been used before. + * Indicates whether this layer has been used already. */ bool empty; }; // struct Layer diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index 2770868..8c70cf9 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -114,6 +114,8 @@ Layer* LayerCache::get(LayerSize& size) { glGenTextures(1, &layer->texture); glBindTexture(GL_TEXTURE_2D, layer->texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 23de3a5..0810fb8 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -366,6 +366,8 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, return false; } + glActiveTexture(GL_TEXTURE0); + LayerSize size(bounds.getWidth(), bounds.getHeight()); Layer* layer = mCaches.layerCache.get(size); if (!layer) { @@ -383,17 +385,22 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, // Copy the framebuffer into the layer glBindTexture(GL_TEXTURE_2D, layer->texture); - if (layer->empty) { - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left, mHeight - bounds.bottom, - bounds.getWidth(), bounds.getHeight(), 0); - layer->empty = false; - } else { - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left, mHeight - bounds.bottom, - bounds.getWidth(), bounds.getHeight()); - } - - if (flags & SkCanvas::kClipToLayer_SaveFlag) { - if (mSnapshot->clipTransformed(bounds)) setScissorFromClip(); + // TODO: Workaround for b/3054204 + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left, mHeight - bounds.bottom, + bounds.getWidth(), bounds.getHeight(), 0); + + // TODO: Waiting for b/3054204 to be fixed +// if (layer->empty) { +// glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left, mHeight - bounds.bottom, +// bounds.getWidth(), bounds.getHeight(), 0); +// layer->empty = false; +// } else { +// glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left, mHeight - bounds.bottom, +// bounds.getWidth(), bounds.getHeight()); +// } + + if (flags & SkCanvas::kClipToLayer_SaveFlag && mSnapshot->clipTransformed(bounds)) { + setScissorFromClip(); } // Enqueue the buffer coordinates to clear the corresponding region later diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 70e06a1..377727b 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -138,8 +138,8 @@ PathTexture* PathCache::addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint) { const SkRect& bounds = path->getBounds(); - const float pathWidth = bounds.width(); - const float pathHeight = bounds.height(); + const float pathWidth = fmax(bounds.width(), 1.0f); + const float pathHeight = fmax(bounds.height(), 1.0f); if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) { LOGW("Path too large to be rendered into a texture"); diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs index 33945a5..f5fecba 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs @@ -65,7 +65,6 @@ static void computeGaussianWeights() { static void copyInput() { - RS_DEBUG_MARKER; rs_allocation ain = rsGetAllocation(InPixel); uint32_t dimx = rsAllocationGetDimX(ain); uint32_t dimy = rsAllocationGetDimY(ain); @@ -74,7 +73,6 @@ static void copyInput() { ScratchPixel1[x + y * dimx] = convert_float4(InPixel[x + y * dimx]); } } - RS_DEBUG_MARKER; } void filter() { diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index cfd6479..6940033 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -241,6 +241,10 @@ bool Context::setupCheck() return true; } +void Context::setupProgramStore() { + mFragmentStore->setupGL2(this, &mStateFragmentStore); +} + static bool getProp(const char *str) { char buf[PROPERTY_VALUE_MAX]; @@ -282,14 +286,14 @@ void * Context::threadProc(void *vrsc) rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms"); rsc->props.mLogVisual = getProp("debug.rs.visual"); - ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; - if (!tlsStruct) { + rsc->mTlsStruct = new ScriptTLSStruct; + if (!rsc->mTlsStruct) { LOGE("Error allocating tls storage"); return NULL; } - tlsStruct->mContext = rsc; - tlsStruct->mScript = NULL; - int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct); + rsc->mTlsStruct->mContext = rsc; + rsc->mTlsStruct->mScript = NULL; + int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct); if (status) { LOGE("pthread_setspecific %i", status); } @@ -361,6 +365,7 @@ void * Context::threadProc(void *vrsc) rsc->deinitEGL(); pthread_mutex_unlock(&gInitMutex); } + delete rsc->mTlsStruct; LOGV("%p, RS Thread exited", rsc); return NULL; @@ -387,6 +392,11 @@ void * Context::helperThreadProc(void *vrsc) #endif setpriority(PRIO_PROCESS, rsc->mWorkers.mNativeThreadId[idx], rsc->mThreadPriority); + int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct); + if (status) { + LOGE("pthread_setspecific %i", status); + } + while(rsc->mRunning) { rsc->mWorkers.mLaunchSignals[idx].wait(); if (rsc->mWorkers.mLaunchCallback) { diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 2e84930..dabe196 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -49,6 +49,24 @@ namespace android { namespace renderscript { +#if 0 +#define CHECK_OBJ(o) { \ + GET_TLS(); \ + if(!ObjectBase::isValid(rsc, (const ObjectBase *)o)) { \ + LOGE("Bad object %p at %s, %i", o, __FILE__, __LINE__); \ + } \ +} +#define CHECK_OBJ_OR_NULL(o) { \ + GET_TLS(); \ + if(o && !ObjectBase::isValid(rsc, (const ObjectBase *)o)) { \ + LOGE("Bad object %p at %s, %i", o, __FILE__, __LINE__); \ + } \ +} +#else +#define CHECK_OBJ(o) +#define CHECK_OBJ_OR_NULL(o) +#endif + class Context { public: @@ -64,6 +82,7 @@ public: Context * mContext; Script * mScript; }; + ScriptTLSStruct *mTlsStruct; typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); @@ -99,6 +118,7 @@ public: Font * getFont() {return mFont.get();} bool setupCheck(); + void setupProgramStore(); bool checkDriver() const {return mEGL.mSurface != 0;} void pause(); diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 12dedac..c516ea9 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -23,6 +23,7 @@ #include "rsFont.h" #include "rsProgramFragment.h" +#include <cutils/properties.h> #include FT_BITMAP_H #include <GLES/gl.h> @@ -268,6 +269,44 @@ FontState::FontState() mRSC = NULL; mLibrary = NULL; setFontColor(0.1f, 0.1f, 0.1f, 1.0f); + + // Get the renderer properties + char property[PROPERTY_VALUE_MAX]; + + // Get the gamma + float gamma = DEFAULT_TEXT_GAMMA; + if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) { + LOGD(" Setting text gamma to %s", property); + gamma = atof(property); + } else { + LOGD(" Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA); + } + + // Get the black gamma threshold + int blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD; + if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) { + LOGD(" Setting text black gamma threshold to %s", property); + blackThreshold = atoi(property); + } else { + LOGD(" Using default text black gamma threshold of %d", + DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD); + } + mBlackThreshold = (float)(blackThreshold) / 255.0f; + + // Get the white gamma threshold + int whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD; + if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) { + LOGD(" Setting text white gamma threshold to %s", property); + whiteThreshold = atoi(property); + } else { + LOGD(" Using default white black gamma threshold of %d", + DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD); + } + mWhiteThreshold = (float)(whiteThreshold) / 255.0f; + + // Compute the gamma tables + mBlackGamma = gamma; + mWhiteGamma = 1.0f / gamma; } FontState::~FontState() @@ -391,12 +430,15 @@ void FontState::initRenderState() shaderString.append("void main() {\n"); shaderString.append(" lowp vec4 col = UNI_Color;\n"); shaderString.append(" col.a = texture2D(UNI_Tex0, varTex0.xy).a;\n"); + shaderString.append(" col.a = pow(col.a, UNI_Gamma);\n"); shaderString.append(" gl_FragColor = col;\n"); shaderString.append("}\n"); const Element *colorElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); + const Element *gammaElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); mRSC->mStateElement.elementBuilderBegin(); mRSC->mStateElement.elementBuilderAdd(colorElem, "Color", 1); + mRSC->mStateElement.elementBuilderAdd(gammaElem, "Gamma", 1); const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC); Type *inputType = new Type(mRSC); @@ -558,9 +600,9 @@ void FontState::issueDrawCommand() { ObjectBaseRef<const ProgramStore> tmpPS(mRSC->getFragmentStore()); mRSC->setFragmentStore(mFontProgramStore.get()); - if(mFontColorDirty) { - mFontShaderFConstant->data(mRSC, &mFontColor, 4*sizeof(float)); - mFontColorDirty = false; + if(mConstantsDirty) { + mFontShaderFConstant->data(mRSC, &mConstants, sizeof(mConstants)); + mConstantsDirty = false; } if (!mRSC->setupCheck()) { @@ -725,18 +767,26 @@ void FontState::renderText(Allocation *alloc, uint32_t start, int len, int x, in } void FontState::setFontColor(float r, float g, float b, float a) { - mFontColor[0] = r; - mFontColor[1] = g; - mFontColor[2] = b; - mFontColor[3] = a; - mFontColorDirty = true; + mConstants.mFontColor[0] = r; + mConstants.mFontColor[1] = g; + mConstants.mFontColor[2] = b; + mConstants.mFontColor[3] = a; + + mConstants.mGamma = 1.0f; + const int luminance = (r * 2.0f + g * 5.0f + b) / 8.0f; + if (luminance <= mBlackThreshold) { + mConstants.mGamma = mBlackGamma; + } else if (luminance >= mWhiteThreshold) { + mConstants.mGamma = mWhiteGamma; + } + mConstantsDirty = true; } void FontState::getFontColor(float *r, float *g, float *b, float *a) const { - *r = mFontColor[0]; - *g = mFontColor[1]; - *b = mFontColor[2]; - *a = mFontColor[3]; + *r = mConstants.mFontColor[0]; + *g = mConstants.mFontColor[1]; + *b = mConstants.mFontColor[2]; + *a = mConstants.mFontColor[3]; } void FontState::deinit(Context *rsc) diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h index 027ed1d..16009ef 100644 --- a/libs/rs/rsFont.h +++ b/libs/rs/rsFont.h @@ -31,6 +31,15 @@ namespace android { namespace renderscript { +// Gamma (>= 1.0, <= 10.0) +#define PROPERTY_TEXT_GAMMA "ro.text_gamma" +#define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "ro.text_gamma.black_threshold" +#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold" + +#define DEFAULT_TEXT_GAMMA 1.4f +#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64 +#define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192 + class FontState; class Font : public ObjectBase @@ -162,8 +171,17 @@ protected: Context *mRSC; - float mFontColor[4]; - bool mFontColorDirty; + struct { + float mFontColor[4]; + float mGamma; + } mConstants; + bool mConstantsDirty; + + float mBlackGamma; + float mWhiteGamma; + + float mBlackThreshold; + float mWhiteThreshold; // Free type library, we only need one copy FT_Library mLibrary; diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp index 713d61e..f69cb15 100644 --- a/libs/rs/rsObjectBase.cpp +++ b/libs/rs/rsObjectBase.cpp @@ -195,3 +195,15 @@ void ObjectBase::dumpAll(Context *rsc) } } +bool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj) +{ + const ObjectBase * o = rsc->mObjHead; + while (o) { + if (o == obj) { + return true; + } + o = o->mNext; + } + return false; +} + diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h index ad95b81..59fb4a6 100644 --- a/libs/rs/rsObjectBase.h +++ b/libs/rs/rsObjectBase.h @@ -56,6 +56,8 @@ public: virtual void serialize(OStream *stream) const = 0; virtual RsA3DClassID getClassId() const = 0; + static bool isValid(const Context *rsc, const ObjectBase *obj); + protected: const char *mAllocFile; uint32_t mAllocLine; diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 2531a9b..10e00e6 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -115,6 +115,14 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, Program::~Program() { + if(mRSC->props.mLogShaders) { + LOGV("Program::~Program with shader id %u", mShaderID); + } + + if(mShaderID) { + glDeleteShader(mShaderID); + } + for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) { bindAllocation(NULL, NULL, ct); } diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 275a1df..c94f294 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -49,6 +49,9 @@ ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, ProgramFragment::~ProgramFragment() { + if(mShaderID) { + mRSC->mShaderCache.cleanupFragment(mShaderID); + } } void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a) diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index bd12989..d3dbfb2 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -45,15 +45,9 @@ ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, ProgramVertex::~ProgramVertex() { -} - -static void logMatrix(const char *txt, const float *f) -{ - LOGV("Matrix %s, %p", txt, f); - LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[0], f[4], f[8], f[12]); - LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[1], f[5], f[9], f[13]); - LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[2], f[6], f[10], f[14]); - LOGV("%6.4f, %6.4f, %6.4f, %6.4f", f[3], f[7], f[11], f[15]); + if(mShaderID) { + mRSC->mShaderCache.cleanupVertex(mShaderID); + } } void ProgramVertex::loadShader(Context *rsc) { diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 22fd421..e0de867 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -203,45 +203,46 @@ static float SC_getDt() static uint32_t SC_allocGetDimX(RsAllocation va) { - GET_TLS(); const Allocation *a = static_cast<const Allocation *>(va); - //LOGE("SC_allocGetDimX a=%p", a); - //LOGE(" type=%p", a->getType()); + CHECK_OBJ(a); + //LOGE("SC_allocGetDimX a=%p type=%p", a, a->getType()); return a->getType()->getDimX(); } static uint32_t SC_allocGetDimY(RsAllocation va) { - GET_TLS(); const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); return a->getType()->getDimY(); } static uint32_t SC_allocGetDimZ(RsAllocation va) { - GET_TLS(); const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); return a->getType()->getDimZ(); } static uint32_t SC_allocGetDimLOD(RsAllocation va) { - GET_TLS(); const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); return a->getType()->getDimLOD(); } static uint32_t SC_allocGetDimFaces(RsAllocation va) { - GET_TLS(); const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); return a->getType()->getDimFaces(); } static const void * SC_getElementAtX(RsAllocation va, uint32_t x) { const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); const Type *t = a->getType(); + CHECK_OBJ(t); const uint8_t *p = (const uint8_t *)a->getPtr(); return &p[t->getElementSizeBytes() * x]; } @@ -249,7 +250,9 @@ static const void * SC_getElementAtX(RsAllocation va, uint32_t x) static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) { const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); const Type *t = a->getType(); + CHECK_OBJ(t); const uint8_t *p = (const uint8_t *)a->getPtr(); return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; } @@ -257,7 +260,9 @@ static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) { const Allocation *a = static_cast<const Allocation *>(va); + CHECK_OBJ(a); const Type *t = a->getType(); + CHECK_OBJ(t); const uint8_t *p = (const uint8_t *)a->getPtr(); return &p[t->getElementSizeBytes() * (x + y*t->getDimX())]; } @@ -265,9 +270,11 @@ static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, static void SC_setObject(void **vdst, void * vsrc) { //LOGE("SC_setObject %p,%p %p", vdst, *vdst, vsrc); if (vsrc) { + CHECK_OBJ(vsrc); static_cast<ObjectBase *>(vsrc)->incSysRef(); } if (vdst[0]) { + CHECK_OBJ(vdst[0]); static_cast<ObjectBase *>(vdst[0])->decSysRef(); } *vdst = vsrc; @@ -276,6 +283,7 @@ static void SC_setObject(void **vdst, void * vsrc) { static void SC_clearObject(void **vdst) { //LOGE("SC_clearObject %p,%p", vdst, *vdst); if (vdst[0]) { + CHECK_OBJ(vdst[0]); static_cast<ObjectBase *>(vdst[0])->decSysRef(); } *vdst = NULL; diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp index fd4c379..88db761 100644 --- a/libs/rs/rsScriptC_LibGL.cpp +++ b/libs/rs/rsScriptC_LibGL.cpp @@ -44,6 +44,8 @@ using namespace android::renderscript; static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) { + CHECK_OBJ_OR_NULL(va); + CHECK_OBJ(vpf); GET_TLS(); rsi_ProgramBindTexture(rsc, static_cast<ProgramFragment *>(vpf), @@ -54,6 +56,8 @@ static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) { + CHECK_OBJ_OR_NULL(vs); + CHECK_OBJ(vpf); GET_TLS(); rsi_ProgramBindSampler(rsc, static_cast<ProgramFragment *>(vpf), @@ -64,24 +68,28 @@ static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) static void SC_bindProgramStore(RsProgramStore pfs) { + CHECK_OBJ_OR_NULL(pfs); GET_TLS(); rsi_ContextBindProgramStore(rsc, pfs); } static void SC_bindProgramFragment(RsProgramFragment pf) { + CHECK_OBJ_OR_NULL(pf); GET_TLS(); rsi_ContextBindProgramFragment(rsc, pf); } static void SC_bindProgramVertex(RsProgramVertex pv) { + CHECK_OBJ_OR_NULL(pv); GET_TLS(); rsi_ContextBindProgramVertex(rsc, pv); } static void SC_bindProgramRaster(RsProgramRaster pv) { + CHECK_OBJ_OR_NULL(pv); GET_TLS(); rsi_ContextBindProgramRaster(rsc, pv); } @@ -112,6 +120,7 @@ static void SC_vpLoadTextureMatrix(const rsc_Matrix *m) static void SC_pfConstantColor(RsProgramFragment vpf, float r, float g, float b, float a) { GET_TLS(); + CHECK_OBJ(vpf); ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); pf->setConstantColor(rsc, r, g, b, a); } @@ -228,6 +237,7 @@ static void SC_drawRect(float x1, float y1, static void SC_drawMesh(RsMesh vsm) { + CHECK_OBJ(vsm); GET_TLS(); Mesh *sm = static_cast<Mesh *>(vsm); if (!rsc->setupCheck()) { @@ -238,6 +248,7 @@ static void SC_drawMesh(RsMesh vsm) static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex) { + CHECK_OBJ(vsm); GET_TLS(); Mesh *sm = static_cast<Mesh *>(vsm); if (!rsc->setupCheck()) { @@ -248,6 +259,7 @@ static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex) static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t start, uint32_t len) { + CHECK_OBJ(vsm); GET_TLS(); Mesh *sm = static_cast<Mesh *>(vsm); if (!rsc->setupCheck()) { @@ -259,6 +271,7 @@ static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t s static void SC_meshComputeBoundingBox(RsMesh vsm, float *minX, float *minY, float *minZ, float *maxX, float *maxY, float *maxZ) { + CHECK_OBJ(vsm); GET_TLS(); Mesh *sm = static_cast<Mesh *>(vsm); sm->computeBBox(); @@ -285,17 +298,20 @@ static void SC_color(float r, float g, float b, float a) static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) { + CHECK_OBJ(va); GET_TLS(); rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel); } static void SC_uploadToTexture(RsAllocation va) { + CHECK_OBJ(va); GET_TLS(); rsi_AllocationUploadToTexture(rsc, va, false, 0); } static void SC_uploadToBufferObject(RsAllocation va) { + CHECK_OBJ(va); GET_TLS(); rsi_AllocationUploadToBufferObject(rsc, va); } @@ -303,9 +319,7 @@ static void SC_uploadToBufferObject(RsAllocation va) static void SC_ClearColor(float r, float g, float b, float a) { GET_TLS(); - if (!rsc->setupCheck()) { - return; - } + rsc->setupProgramStore(); glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT); @@ -314,9 +328,7 @@ static void SC_ClearColor(float r, float g, float b, float a) static void SC_ClearDepth(float v) { GET_TLS(); - if (!rsc->setupCheck()) { - return; - } + rsc->setupProgramStore(); glClearDepthf(v); glClear(GL_DEPTH_BUFFER_BIT); @@ -336,6 +348,7 @@ static uint32_t SC_getHeight() static void SC_DrawTextAlloc(RsAllocation va, int x, int y) { + CHECK_OBJ(va); GET_TLS(); Allocation *alloc = static_cast<Allocation *>(va); rsc->mStateFont.renderText(alloc, x, y); @@ -349,6 +362,7 @@ static void SC_DrawText(const char *text, int x, int y) static void SC_BindFont(RsFont font) { + CHECK_OBJ(font); GET_TLS(); rsi_ContextBindFont(rsc, font); } diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp index 28e3b1d..45f6207 100644 --- a/libs/rs/rsShaderCache.cpp +++ b/libs/rs/rsShaderCache.cpp @@ -29,20 +29,15 @@ using namespace android::renderscript; ShaderCache::ShaderCache() { - mEntryCount = 0; - mEntryAllocationCount = 16; - mEntries = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); + mEntries.setCapacity(16); } ShaderCache::~ShaderCache() { - for (uint32_t ct=0; ct < mEntryCount; ct++) { - glDeleteProgram(mEntries[ct].program); + for (uint32_t ct=0; ct < mEntries.size(); ct++) { + glDeleteProgram(mEntries[ct]->program); + free(mEntries[ct]); } - - mEntryCount = 0; - mEntryAllocationCount = 0; - free(mEntries); } bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag) @@ -59,44 +54,30 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag return false; } //LOGV("ShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); - - for (uint32_t ct=0; ct < mEntryCount; ct++) { - if ((mEntries[ct].vtx == vtx->getShaderID()) && - (mEntries[ct].frag == frag->getShaderID())) { - - //LOGV("SC using program %i", mEntries[ct].program); - glUseProgram(mEntries[ct].program); - mCurrent = &mEntries[ct]; + uint32_t entryCount = mEntries.size(); + for(uint32_t ct = 0; ct < entryCount; ct ++) { + if ((mEntries[ct]->vtx == vtx->getShaderID()) && + (mEntries[ct]->frag == frag->getShaderID())) { + + //LOGV("SC using program %i", mEntries[ct]->program); + glUseProgram(mEntries[ct]->program); + mCurrent = mEntries[ct]; //LOGV("ShaderCache hit, using %i", ct); rsc->checkError("ShaderCache::lookup (hit)"); return true; } } - // Not in cache, add it. - - if (mEntryAllocationCount == mEntryCount) { - // Out of space, make some. - mEntryAllocationCount *= 2; - entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); - if (!e) { - LOGE("Out of memory for ShaderCache::lookup"); - return false; - } - memcpy(e, mEntries, sizeof(entry_t) * mEntryCount); - free(mEntries); - mEntries = e; - } - //LOGV("ShaderCache miss, using %i", mEntryCount); + //LOGV("ShaderCache miss"); //LOGE("e0 %x", glGetError()); - - entry_t *e = &mEntries[mEntryCount]; + entry_t *e = (entry_t *)malloc(sizeof(entry_t)); + mEntries.push(e); mCurrent = e; e->vtx = vtx->getShaderID(); e->frag = frag->getShaderID(); e->program = glCreateProgram(); e->vtxAttrCount = vtx->getAttribCount(); - if (mEntries[mEntryCount].program) { + if (e->program) { GLuint pgm = e->program; glAttachShader(pgm, vtx->getShaderID()); //LOGE("e1 %x", glGetError()); @@ -155,7 +136,6 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag e->mIsValid = true; //LOGV("SC made program %i", e->program); glUseProgram(e->program); - mEntryCount++; rsc->checkError("ShaderCache::lookup (miss)"); return true; } @@ -171,10 +151,32 @@ int32_t ShaderCache::vtxAttribSlot(const String8 &attrName) const { void ShaderCache::cleanupVertex(uint32_t id) { + int32_t numEntries = (int32_t)mEntries.size(); + for(int32_t ct = 0; ct < numEntries; ct ++) { + if (mEntries[ct]->vtx == id) { + glDeleteProgram(mEntries[ct]->program); + + free(mEntries[ct]); + mEntries.removeAt(ct); + numEntries = (int32_t)mEntries.size(); + ct --; + } + } } void ShaderCache::cleanupFragment(uint32_t id) { + int32_t numEntries = (int32_t)mEntries.size(); + for(int32_t ct = 0; ct < numEntries; ct ++) { + if (mEntries[ct]->frag == id) { + glDeleteProgram(mEntries[ct]->program); + + free(mEntries[ct]); + mEntries.removeAt(ct); + numEntries = (int32_t)mEntries.size(); + ct --; + } + } } void ShaderCache::cleanupAll() diff --git a/libs/rs/rsShaderCache.h b/libs/rs/rsShaderCache.h index 312c251..35ff95b 100644 --- a/libs/rs/rsShaderCache.h +++ b/libs/rs/rsShaderCache.h @@ -58,11 +58,12 @@ protected: int32_t mFragUniformSlots[Program::MAX_UNIFORMS]; bool mIsValid; } entry_t; - entry_t *mEntries; + //entry_t *mEntries; + Vector<entry_t*> mEntries; entry_t *mCurrent; - uint32_t mEntryCount; - uint32_t mEntryAllocationCount; + /*uint32_t mEntryCount; + uint32_t mEntryAllocationCount;*/ }; diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp index 040060e..d676f5e 100644 --- a/libs/surfaceflinger_client/ISurfaceComposer.cpp +++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp @@ -126,11 +126,14 @@ public: virtual status_t captureScreen(DisplayID dpy, sp<IMemoryHeap>* heap, - uint32_t* width, uint32_t* height, PixelFormat* format) + uint32_t* width, uint32_t* height, PixelFormat* format, + uint32_t reqWidth, uint32_t reqHeight) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInt32(dpy); + data.writeInt32(reqWidth); + data.writeInt32(reqHeight); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder()); *width = reply.readInt32(); @@ -208,10 +211,13 @@ status_t BnSurfaceComposer::onTransact( case CAPTURE_SCREEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); DisplayID dpy = data.readInt32(); + uint32_t reqWidth = data.readInt32(); + uint32_t reqHeight = data.readInt32(); sp<IMemoryHeap> heap; uint32_t w, h; PixelFormat f; - status_t res = captureScreen(dpy, &heap, &w, &h, &f); + status_t res = captureScreen(dpy, &heap, &w, &h, &f, + reqWidth, reqHeight); 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 4096ac6..f270461 100644 --- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp @@ -545,5 +545,55 @@ status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) } // ---------------------------------------------------------------------------- + +ScreenshotClient::ScreenshotClient() + : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) { +} + +status_t ScreenshotClient::update() { + sp<ISurfaceComposer> s(ComposerService::getComposerService()); + if (s == NULL) return NO_INIT; + mHeap = 0; + return s->captureScreen(0, &mHeap, + &mWidth, &mHeight, &mFormat, 0, 0); +} + +status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) { + sp<ISurfaceComposer> s(ComposerService::getComposerService()); + if (s == NULL) return NO_INIT; + mHeap = 0; + return s->captureScreen(0, &mHeap, + &mWidth, &mHeight, &mFormat, reqWidth, reqHeight); +} + +void ScreenshotClient::release() { + mHeap = 0; +} + +void const* ScreenshotClient::getPixels() const { + return mHeap->getBase(); +} + +uint32_t ScreenshotClient::getWidth() const { + return mWidth; +} + +uint32_t ScreenshotClient::getHeight() const { + return mHeight; +} + +PixelFormat ScreenshotClient::getFormat() const { + return mFormat; +} + +uint32_t ScreenshotClient::getStride() const { + return mWidth; +} + +size_t ScreenshotClient::getSize() const { + return mHeap->getSize(); +} + +// ---------------------------------------------------------------------------- }; // namespace android diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index f2b029a..825febc 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -33,6 +33,9 @@ #include <math.h> #define INDENT " " +#define INDENT2 " " +#define INDENT3 " " +#define INDENT4 " " namespace android { @@ -63,6 +66,10 @@ inline static float pythag(float x, float y) { return sqrtf(x * x + y * y); } +static inline const char* toString(bool value) { + return value ? "true" : "false"; +} + int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) { int32_t mask; @@ -236,16 +243,14 @@ void InputReader::addDevice(nsecs_t when, int32_t deviceId) { String8 name = mEventHub->getDeviceName(deviceId); uint32_t classes = mEventHub->getDeviceClasses(deviceId); - // Write a log message about the added device as a heading for subsequent log messages. - LOGI("Device added: id=0x%x, name=%s", deviceId, name.string()); - InputDevice* device = createDevice(deviceId, name, classes); device->configure(); if (device->isIgnored()) { - LOGI(INDENT "Sources: none (device is ignored)"); + LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", deviceId, name.string()); } else { - LOGI(INDENT "Sources: 0x%08x", device->getSources()); + LOGI("Device added: id=0x%x, name=%s, sources=%08x", deviceId, name.string(), + device->getSources()); } bool added = false; @@ -287,7 +292,6 @@ void InputReader::removeDevice(nsecs_t when, int32_t deviceId) { return; } - // Write a log message about the removed device as a heading for subsequent log messages. if (device->isIgnored()) { LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)", device->getId(), device->getName().string()); @@ -571,59 +575,15 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s } void InputReader::dump(String8& dump) { - dumpDeviceInfo(dump); -} - -static void dumpMotionRange(String8& dump, - const char* name, const InputDeviceInfo::MotionRange* range) { - if (range) { - dump.appendFormat(" %s = { min: %0.3f, max: %0.3f, flat: %0.3f, fuzz: %0.3f }\n", - name, range->min, range->max, range->flat, range->fuzz); - } -} - -#define DUMP_MOTION_RANGE(range) \ - dumpMotionRange(dump, #range, deviceInfo.getMotionRange(AINPUT_MOTION_RANGE_##range)); - -void InputReader::dumpDeviceInfo(String8& dump) { - Vector<int32_t> deviceIds; - getInputDeviceIds(deviceIds); - - InputDeviceInfo deviceInfo; - for (size_t i = 0; i < deviceIds.size(); i++) { - int32_t deviceId = deviceIds[i]; + { // acquire device registry reader lock + RWLock::AutoRLock _rl(mDeviceRegistryLock); - status_t result = getInputDeviceInfo(deviceId, & deviceInfo); - if (result == NAME_NOT_FOUND) { - continue; - } else if (result != OK) { - dump.appendFormat(" ** Unexpected error %d getting information about input devices.\n", - result); - continue; + for (size_t i = 0; i < mDevices.size(); i++) { + mDevices.valueAt(i)->dump(dump); } - - dump.appendFormat(" Device %d: '%s'\n", - deviceInfo.getId(), deviceInfo.getName().string()); - dump.appendFormat(" sources = 0x%08x\n", - deviceInfo.getSources()); - dump.appendFormat(" keyboardType = %d\n", - deviceInfo.getKeyboardType()); - - dump.append(" motion ranges:\n"); - DUMP_MOTION_RANGE(X); - DUMP_MOTION_RANGE(Y); - DUMP_MOTION_RANGE(PRESSURE); - DUMP_MOTION_RANGE(SIZE); - DUMP_MOTION_RANGE(TOUCH_MAJOR); - DUMP_MOTION_RANGE(TOUCH_MINOR); - DUMP_MOTION_RANGE(TOOL_MAJOR); - DUMP_MOTION_RANGE(TOOL_MINOR); - DUMP_MOTION_RANGE(ORIENTATION); - } + } // release device registy reader lock } -#undef DUMP_MOTION_RANGE - // --- InputReaderThread --- @@ -654,6 +614,43 @@ InputDevice::~InputDevice() { mMappers.clear(); } +static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo, + int32_t rangeType, const char* name) { + const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType); + if (range) { + dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n", + name, range->min, range->max, range->flat, range->fuzz); + } +} + +void InputDevice::dump(String8& dump) { + InputDeviceInfo deviceInfo; + getDeviceInfo(& deviceInfo); + + dump.appendFormat(INDENT "Device 0x%x: %s\n", deviceInfo.getId(), + deviceInfo.getName().string()); + dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); + dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); + if (!deviceInfo.getMotionRanges().isEmpty()) { + dump.append(INDENT2 "Motion Ranges:\n"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor"); + dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation"); + } + + size_t numMappers = mMappers.size(); + for (size_t i = 0; i < numMappers; i++) { + InputMapper* mapper = mMappers[i]; + mapper->dump(dump); + } +} + void InputDevice::addMapper(InputMapper* mapper) { mMappers.add(mapper); } @@ -763,6 +760,9 @@ void InputMapper::populateDeviceInfo(InputDeviceInfo* info) { info->addSource(getSources()); } +void InputMapper::dump(String8& dump) { +} + void InputMapper::configure() { } @@ -856,6 +856,19 @@ void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) { info->setKeyboardType(mKeyboardType); } +void KeyboardInputMapper::dump(String8& dump) { + { // acquire lock + AutoMutex _l(mLock); + dump.append(INDENT2 "Keyboard Input Mapper:\n"); + dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); + dump.appendFormat(INDENT3 "Sources: 0x%x\n", mSources); + dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType); + dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size()); + dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState); + dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); + } // release lock +} + void KeyboardInputMapper::reset() { for (;;) { int32_t keyCode, scanCode; @@ -980,7 +993,10 @@ void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFl int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP; int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM; if (policyFlags & POLICY_FLAG_WOKE_HERE) { - keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE; + keyEventFlags |= AKEY_EVENT_FLAG_WOKE_HERE; + } + if (policyFlags & POLICY_FLAG_VIRTUAL) { + keyEventFlags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; } getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, @@ -1044,6 +1060,18 @@ void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) { info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale); } +void TrackballInputMapper::dump(String8& dump) { + { // acquire lock + AutoMutex _l(mLock); + dump.append(INDENT2 "Trackball Input Mapper:\n"); + dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); + dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision); + dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision); + dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down)); + dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); + } // release lock +} + void TrackballInputMapper::initializeLocked() { mAccumulator.clear(); @@ -1275,6 +1303,21 @@ void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { } // release lock } +void TouchInputMapper::dump(String8& dump) { + { // acquire lock + AutoMutex _l(mLock); + dump.append(INDENT2 "Touch Input Mapper:\n"); + dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); + dumpParameters(dump); + dumpVirtualKeysLocked(dump); + dumpRawAxes(dump); + dumpCalibration(dump); + dumpSurfaceLocked(dump); + dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mLocked.xPrecision); + dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mLocked.yPrecision); + } // release lock +} + void TouchInputMapper::initializeLocked() { mCurrentTouch.clear(); mLastTouch.clear(); @@ -1301,16 +1344,13 @@ void TouchInputMapper::configure() { // Configure basic parameters. configureParameters(); - logParameters(); // Configure absolute axis information. configureRawAxes(); - logRawAxes(); // Prepare input device calibration. parseCalibration(); resolveCalibration(); - logCalibration(); { // acquire lock AutoMutex _l(mLock); @@ -1326,16 +1366,13 @@ void TouchInputMapper::configureParameters() { mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents(); } -void TouchInputMapper::logParameters() { - if (mParameters.useBadTouchFilter) { - LOGI(INDENT "Bad touch filter enabled."); - } - if (mParameters.useAveragingTouchFilter) { - LOGI(INDENT "Averaging touch filter enabled."); - } - if (mParameters.useJumpyTouchFilter) { - LOGI(INDENT "Jumpy touch filter enabled."); - } +void TouchInputMapper::dumpParameters(String8& dump) { + dump.appendFormat(INDENT3 "UseBadTouchFilter: %s\n", + toString(mParameters.useBadTouchFilter)); + dump.appendFormat(INDENT3 "UseAveragingTouchFilter: %s\n", + toString(mParameters.useAveragingTouchFilter)); + dump.appendFormat(INDENT3 "UseJumpyTouchFilter: %s\n", + toString(mParameters.useJumpyTouchFilter)); } void TouchInputMapper::configureRawAxes() { @@ -1349,24 +1386,25 @@ void TouchInputMapper::configureRawAxes() { mRawAxes.orientation.clear(); } -static void logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) { +static void dumpAxisInfo(String8& dump, RawAbsoluteAxisInfo axis, const char* name) { if (axis.valid) { - LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d", + dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n", name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz); } else { - LOGI(INDENT "Raw %s axis: unknown range", name); + dump.appendFormat(INDENT4 "%s: unknown range\n", name); } } -void TouchInputMapper::logRawAxes() { - logAxisInfo(mRawAxes.x, "x"); - logAxisInfo(mRawAxes.y, "y"); - logAxisInfo(mRawAxes.pressure, "pressure"); - logAxisInfo(mRawAxes.touchMajor, "touchMajor"); - logAxisInfo(mRawAxes.touchMinor, "touchMinor"); - logAxisInfo(mRawAxes.toolMajor, "toolMajor"); - logAxisInfo(mRawAxes.toolMinor, "toolMinor"); - logAxisInfo(mRawAxes.orientation, "orientation"); +void TouchInputMapper::dumpRawAxes(String8& dump) { + dump.append(INDENT3 "Raw Axes:\n"); + dumpAxisInfo(dump, mRawAxes.x, "X"); + dumpAxisInfo(dump, mRawAxes.y, "Y"); + dumpAxisInfo(dump, mRawAxes.pressure, "Pressure"); + dumpAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor"); + dumpAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor"); + dumpAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor"); + dumpAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor"); + dumpAxisInfo(dump, mRawAxes.orientation, "Orientation"); } bool TouchInputMapper::configureSurfaceLocked() { @@ -1391,10 +1429,8 @@ bool TouchInputMapper::configureSurfaceLocked() { bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height; if (sizeChanged) { - LOGI("Device reconfigured (display size changed): id=0x%x, name=%s", - getDeviceId(), getDeviceName().string()); - LOGI(INDENT "Width: %dpx", width); - LOGI(INDENT "Height: %dpx", height); + LOGI("Device reconfigured: id=0x%x, name=%s, display size is now %dx%d", + getDeviceId(), getDeviceName().string(), width, height); mLocked.surfaceWidth = width; mLocked.surfaceHeight = height; @@ -1562,39 +1598,13 @@ bool TouchInputMapper::configureSurfaceLocked() { mLocked.orientedRanges.y.fuzz = orientedYScale; } - if (sizeChanged) { - logMotionRangesLocked(); - } - return true; } -static void logMotionRangeInfo(InputDeviceInfo::MotionRange* range, const char* name) { - if (range) { - LOGI(INDENT "Output %s range: min=%f, max=%f, flat=%f, fuzz=%f", - name, range->min, range->max, range->flat, range->fuzz); - } else { - LOGI(INDENT "Output %s range: unsupported", name); - } -} - -void TouchInputMapper::logMotionRangesLocked() { - logMotionRangeInfo(& mLocked.orientedRanges.x, "x"); - logMotionRangeInfo(& mLocked.orientedRanges.y, "y"); - logMotionRangeInfo(mLocked.orientedRanges.havePressure - ? & mLocked.orientedRanges.pressure : NULL, "pressure"); - logMotionRangeInfo(mLocked.orientedRanges.haveSize - ? & mLocked.orientedRanges.size : NULL, "size"); - logMotionRangeInfo(mLocked.orientedRanges.haveTouchArea - ? & mLocked.orientedRanges.touchMajor : NULL, "touchMajor"); - logMotionRangeInfo(mLocked.orientedRanges.haveTouchArea - ? & mLocked.orientedRanges.touchMinor : NULL, "touchMinor"); - logMotionRangeInfo(mLocked.orientedRanges.haveToolArea - ? & mLocked.orientedRanges.toolMajor : NULL, "toolMajor"); - logMotionRangeInfo(mLocked.orientedRanges.haveToolArea - ? & mLocked.orientedRanges.toolMinor : NULL, "toolMinor"); - logMotionRangeInfo(mLocked.orientedRanges.haveOrientation - ? & mLocked.orientedRanges.orientation : NULL, "orientation"); +void TouchInputMapper::dumpSurfaceLocked(String8& dump) { + dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth); + dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight); + dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation); } void TouchInputMapper::configureVirtualKeysLocked() { @@ -1651,9 +1661,21 @@ void TouchInputMapper::configureVirtualKeysLocked() { virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; - LOGI(INDENT "VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d", - virtualKey.scanCode, virtualKey.keyCode, - virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom); + } +} + +void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) { + if (!mLocked.virtualKeys.isEmpty()) { + dump.append(INDENT3 "Virtual Keys:\n"); + + for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) { + const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i); + dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, " + "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n", + i, virtualKey.scanCode, virtualKey.keyCode, + virtualKey.hitLeft, virtualKey.hitRight, + virtualKey.hitTop, virtualKey.hitBottom); + } } } @@ -1861,19 +1883,19 @@ void TouchInputMapper::resolveCalibration() { } } -void TouchInputMapper::logCalibration() { - LOGI(INDENT "Calibration:"); +void TouchInputMapper::dumpCalibration(String8& dump) { + dump.append(INDENT3 "Calibration:\n"); // Touch Area switch (mCalibration.touchAreaCalibration) { case Calibration::TOUCH_AREA_CALIBRATION_NONE: - LOGI(INDENT INDENT "touch.touchArea.calibration: none"); + dump.append(INDENT4 "touch.touchArea.calibration: none\n"); break; case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC: - LOGI(INDENT INDENT "touch.touchArea.calibration: geometric"); + dump.append(INDENT4 "touch.touchArea.calibration: geometric\n"); break; case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE: - LOGI(INDENT INDENT "touch.touchArea.calibration: pressure"); + dump.append(INDENT4 "touch.touchArea.calibration: pressure\n"); break; default: assert(false); @@ -1882,40 +1904,43 @@ void TouchInputMapper::logCalibration() { // Tool Area switch (mCalibration.toolAreaCalibration) { case Calibration::TOOL_AREA_CALIBRATION_NONE: - LOGI(INDENT INDENT "touch.toolArea.calibration: none"); + dump.append(INDENT4 "touch.toolArea.calibration: none\n"); break; case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC: - LOGI(INDENT INDENT "touch.toolArea.calibration: geometric"); + dump.append(INDENT4 "touch.toolArea.calibration: geometric\n"); break; case Calibration::TOOL_AREA_CALIBRATION_LINEAR: - LOGI(INDENT INDENT "touch.toolArea.calibration: linear"); + dump.append(INDENT4 "touch.toolArea.calibration: linear\n"); break; default: assert(false); } if (mCalibration.haveToolAreaLinearScale) { - LOGI(INDENT INDENT "touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale); + dump.appendFormat(INDENT4 "touch.toolArea.linearScale: %0.3f\n", + mCalibration.toolAreaLinearScale); } if (mCalibration.haveToolAreaLinearBias) { - LOGI(INDENT INDENT "touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias); + dump.appendFormat(INDENT4 "touch.toolArea.linearBias: %0.3f\n", + mCalibration.toolAreaLinearBias); } if (mCalibration.haveToolAreaIsSummed) { - LOGI(INDENT INDENT "touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed); + dump.appendFormat(INDENT4 "touch.toolArea.isSummed: %d\n", + mCalibration.toolAreaIsSummed); } // Pressure switch (mCalibration.pressureCalibration) { case Calibration::PRESSURE_CALIBRATION_NONE: - LOGI(INDENT INDENT "touch.pressure.calibration: none"); + dump.append(INDENT4 "touch.pressure.calibration: none\n"); break; case Calibration::PRESSURE_CALIBRATION_PHYSICAL: - LOGI(INDENT INDENT "touch.pressure.calibration: physical"); + dump.append(INDENT4 "touch.pressure.calibration: physical\n"); break; case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: - LOGI(INDENT INDENT "touch.pressure.calibration: amplitude"); + dump.append(INDENT4 "touch.pressure.calibration: amplitude\n"); break; default: assert(false); @@ -1923,10 +1948,10 @@ void TouchInputMapper::logCalibration() { switch (mCalibration.pressureSource) { case Calibration::PRESSURE_SOURCE_PRESSURE: - LOGI(INDENT INDENT "touch.pressure.source: pressure"); + dump.append(INDENT4 "touch.pressure.source: pressure\n"); break; case Calibration::PRESSURE_SOURCE_TOUCH: - LOGI(INDENT INDENT "touch.pressure.source: touch"); + dump.append(INDENT4 "touch.pressure.source: touch\n"); break; case Calibration::PRESSURE_SOURCE_DEFAULT: break; @@ -1935,16 +1960,17 @@ void TouchInputMapper::logCalibration() { } if (mCalibration.havePressureScale) { - LOGI(INDENT INDENT "touch.pressure.scale: %f", mCalibration.pressureScale); + dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n", + mCalibration.pressureScale); } // Size switch (mCalibration.sizeCalibration) { case Calibration::SIZE_CALIBRATION_NONE: - LOGI(INDENT INDENT "touch.size.calibration: none"); + dump.append(INDENT4 "touch.size.calibration: none\n"); break; case Calibration::SIZE_CALIBRATION_NORMALIZED: - LOGI(INDENT INDENT "touch.size.calibration: normalized"); + dump.append(INDENT4 "touch.size.calibration: normalized\n"); break; default: assert(false); @@ -1953,10 +1979,10 @@ void TouchInputMapper::logCalibration() { // Orientation switch (mCalibration.orientationCalibration) { case Calibration::ORIENTATION_CALIBRATION_NONE: - LOGI(INDENT INDENT "touch.orientation.calibration: none"); + dump.append(INDENT4 "touch.orientation.calibration: none\n"); break; case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: - LOGI(INDENT INDENT "touch.orientation.calibration: interpolated"); + dump.append(INDENT4 "touch.orientation.calibration: interpolated\n"); break; default: assert(false); @@ -2139,10 +2165,7 @@ void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t p int32_t keyCode, int32_t scanCode, nsecs_t downTime) { int32_t metaState = mContext->getGlobalMetaState(); - if (keyEventAction == AKEY_EVENT_ACTION_DOWN) { - getPolicy()->virtualKeyDownFeedback(); - } - + policyFlags |= POLICY_FLAG_VIRTUAL; int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(), keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags); |
