diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/binder/Parcel.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/Android.mk | 2 | ||||
-rw-r--r-- | libs/hwui/Caches.cpp | 47 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 13 | ||||
-rw-r--r-- | libs/hwui/Extensions.h | 3 | ||||
-rw-r--r-- | libs/hwui/GammaFontRenderer.cpp | 63 | ||||
-rw-r--r-- | libs/hwui/GammaFontRenderer.h | 39 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.h | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 5 | ||||
-rw-r--r-- | libs/hwui/TextureCache.cpp | 31 | ||||
-rw-r--r-- | libs/hwui/TextureCache.h | 13 | ||||
-rw-r--r-- | libs/rs/rsScript.cpp | 19 | ||||
-rw-r--r-- | libs/rs/rsScript.h | 1 | ||||
-rw-r--r-- | libs/utils/CallStack.cpp | 4 |
16 files changed, 239 insertions, 54 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index c557b03..6cd43aa 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -710,24 +710,27 @@ status_t Parcel::writeNativeHandle(const native_handle* handle) return err; } -status_t Parcel::writeFileDescriptor(int fd) +status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) { flat_binder_object obj; obj.type = BINDER_TYPE_FD; obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; obj.handle = fd; - obj.cookie = (void*)0; + obj.cookie = (void*) (takeOwnership ? 1 : 0); return writeObject(obj, true); } status_t Parcel::writeDupFileDescriptor(int fd) { - flat_binder_object obj; - obj.type = BINDER_TYPE_FD; - obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; - obj.handle = dup(fd); - obj.cookie = (void*)1; - return writeObject(obj, true); + int dupFd = dup(fd); + if (dupFd < 0) { + return -errno; + } + status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/); + if (err) { + close(dupFd); + } + return err; } status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) @@ -764,7 +767,7 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) } else { status = writeInt32(1); if (!status) { - status = writeFileDescriptor(fd); + status = writeFileDescriptor(fd, true /*takeOwnership*/); if (!status) { outBlob->init(true /*mapped*/, ptr, len); return NO_ERROR; diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 9bfc94c..95e0a18 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -38,7 +38,7 @@ ifeq ($(USE_OPENGL_RENDERER),true) external/skia/src/ports \ external/skia/include/utils - LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER + LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 24ec4e8..f293cba 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -46,22 +46,16 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// -Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO), - lastDstMode(GL_ZERO), currentProgram(NULL) { +Caches::Caches(): Singleton<Caches>(), mInitialized(false) { GLint maxTextureUnits; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); if (maxTextureUnits < REQUIRED_TEXTURE_UNITS_COUNT) { LOGW("At least %d texture units are required!", REQUIRED_TEXTURE_UNITS_COUNT); } - glGenBuffers(1, &meshBuffer); - glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); - mCurrentBuffer = meshBuffer; - mRegionMesh = NULL; + init(); mDebugLevel = readDebugLevel(); LOGD("Enabling debug mode %d", mDebugLevel); @@ -71,8 +65,40 @@ Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO), #endif } -Caches::~Caches() { +void Caches::init() { + if (mInitialized) return; + + glGenBuffers(1, &meshBuffer); + glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); + + mCurrentBuffer = meshBuffer; + mRegionMesh = NULL; + + blend = false; + lastSrcMode = GL_ZERO; + lastDstMode = GL_ZERO; + currentProgram = NULL; + + mInitialized = true; +} + +void Caches::terminate() { + if (!mInitialized) return; + + glDeleteBuffers(1, &meshBuffer); + mCurrentBuffer = 0; + + glDeleteBuffers(1, &mRegionMeshIndices); delete[] mRegionMesh; + mRegionMesh = NULL; + + fboCache.clear(); + + programCache.clear(); + currentProgram = NULL; + + mInitialized = false; } /////////////////////////////////////////////////////////////////////////////// @@ -170,8 +196,11 @@ void Caches::flush(FlushMode mode) { patchCache.clear(); dropShadowCache.clear(); gradientCache.clear(); + fontRenderer.clear(); // fall through case kFlushMode_Moderate: + fontRenderer.flush(); + textureCache.flush(); pathCache.clear(); roundRectShapeCache.clear(); circleShapeCache.clear(); diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 9b0d7c6..5e58a9e 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -86,7 +86,6 @@ struct CacheLogger { class ANDROID_API Caches: public Singleton<Caches> { Caches(); - ~Caches(); friend class Singleton<Caches>; @@ -109,6 +108,11 @@ public: }; /** + * Initializes the cache. + */ + void init(); + + /** * Flush the cache. * * @param mode Indicates how much of the cache should be flushed @@ -116,6 +120,12 @@ public: void flush(FlushMode mode); /** + * Destroys all resources associated with this cache. This should + * be called after a flush(kFlushMode_Full). + */ + void terminate(); + + /** * Indicates whether the renderer is in debug mode. * This debug mode provides limited information to app developers. */ @@ -194,6 +204,7 @@ public: private: DebugLevel mDebugLevel; + bool mInitialized; }; // class Caches }; // namespace uirenderer diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h index 38d1130..48e4247 100644 --- a/libs/hwui/Extensions.h +++ b/libs/hwui/Extensions.h @@ -66,6 +66,7 @@ public: mHasNPot = hasExtension("GL_OES_texture_npot"); mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch"); + mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer"); const char* vendor = (const char*) glGetString(GL_VENDOR); EXT_LOGD("Vendor: %s", vendor); @@ -80,6 +81,7 @@ public: inline bool hasNPot() const { return mHasNPot; } inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; } inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; } + inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; } bool hasExtension(const char* extension) const { const String8 s(extension); @@ -98,6 +100,7 @@ private: bool mHasNPot; bool mNeedsHighpTexCoords; bool mHasFramebufferFetch; + bool mHasDiscardFramebuffer; }; // class Extensions }; // namespace uirenderer diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp index e8362dc..eb863e9 100644 --- a/libs/hwui/GammaFontRenderer.cpp +++ b/libs/hwui/GammaFontRenderer.cpp @@ -67,20 +67,63 @@ GammaFontRenderer::GammaFontRenderer() { const float whiteGamma = 1.0f / gamma; for (uint32_t i = 0; i <= 255; i++) { - mDefault[i] = i; + mGammaTable[i] = i; const float v = i / 255.0f; const float black = pow(v, blackGamma); const float white = pow(v, whiteGamma); - mBlackGamma[i] = uint8_t((float)::floor(black * 255.0f + 0.5f)); - mWhiteGamma[i] = uint8_t((float)::floor(white * 255.0f + 0.5f)); + mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f)); + mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f)); } - // Configure the font renderers - mDefaultRenderer.setGammaTable(&mDefault[0]); - mBlackGammaRenderer.setGammaTable(&mBlackGamma[0]); - mWhiteGammaRenderer.setGammaTable(&mWhiteGamma[0]); + memset(mRenderers, 0, sizeof(FontRenderer*) * kGammaCount); + memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount); +} + +GammaFontRenderer::~GammaFontRenderer() { + for (int i = 0; i < kGammaCount; i++) { + delete mRenderers[i]; + } +} + +void GammaFontRenderer::clear() { + for (int i = 0; i < kGammaCount; i++) { + delete mRenderers[i]; + mRenderers[i] = NULL; + } +} + +void GammaFontRenderer::flush() { + int count = 0; + int min = -1; + uint32_t minCount = UINT_MAX; + + for (int i = 0; i < kGammaCount; i++) { + if (mRenderers[i]) { + count++; + if (mRenderersUsageCount[i] < minCount) { + minCount = mRenderersUsageCount[i]; + min = i; + } + } + } + + if (count <= 1 || min < 0) return; + + delete mRenderers[min]; + mRenderers[min] = NULL; +} + +FontRenderer* GammaFontRenderer::getRenderer(Gamma gamma) { + FontRenderer* renderer = mRenderers[gamma]; + if (!renderer) { + renderer = new FontRenderer(); + mRenderers[gamma] = renderer; + renderer->setGammaTable(&mGammaTable[gamma * 256]); + } + mRenderersUsageCount[gamma]++; + return renderer; } FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) { @@ -92,12 +135,12 @@ FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) { const int luminance = (r * 2 + g * 5 + b) >> 3; if (luminance <= mBlackThreshold) { - return mBlackGammaRenderer; + return *getRenderer(kGammaBlack); } else if (luminance >= mWhiteThreshold) { - return mWhiteGammaRenderer; + return *getRenderer(kGammaWhite); } } - return mDefaultRenderer; + return *getRenderer(kGammaDefault); } }; // namespace uirenderer diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h index 96d960c..54c208e 100644 --- a/libs/hwui/GammaFontRenderer.h +++ b/libs/hwui/GammaFontRenderer.h @@ -26,36 +26,43 @@ namespace uirenderer { struct GammaFontRenderer { GammaFontRenderer(); + ~GammaFontRenderer(); + + enum Gamma { + kGammaDefault = 0, + kGammaBlack = 1, + kGammaWhite = 2, + kGammaCount = 3 + }; + + void clear(); + void flush(); FontRenderer& getFontRenderer(const SkPaint* paint); uint32_t getFontRendererCount() const { - return 3; + return kGammaCount; } uint32_t getFontRendererSize(uint32_t fontRenderer) const { - switch (fontRenderer) { - case 0: - return mDefaultRenderer.getCacheHeight() * mDefaultRenderer.getCacheWidth(); - case 1: - return mBlackGammaRenderer.getCacheHeight() * mBlackGammaRenderer.getCacheWidth(); - case 2: - return mWhiteGammaRenderer.getCacheHeight() * mWhiteGammaRenderer.getCacheWidth(); - } - return 0; + if (fontRenderer >= kGammaCount) return 0; + + FontRenderer* renderer = mRenderers[fontRenderer]; + if (!renderer) return 0; + + return renderer->getCacheHeight() * renderer->getCacheWidth(); } private: - FontRenderer mDefaultRenderer; - FontRenderer mBlackGammaRenderer; - FontRenderer mWhiteGammaRenderer; + FontRenderer* getRenderer(Gamma gamma); + + uint32_t mRenderersUsageCount[kGammaCount]; + FontRenderer* mRenderers[kGammaCount]; int mBlackThreshold; int mWhiteThreshold; - uint8_t mDefault[256]; - uint8_t mBlackGamma[256]; - uint8_t mWhiteGamma[256]; + uint8_t mGammaTable[256 * kGammaCount]; }; }; // namespace uirenderer diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index e38b479..b7c079b 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -305,8 +305,10 @@ void LayerRenderer::destroyLayer(Layer* layer) { LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d", layer->getWidth(), layer->getHeight(), layer->getFbo()); - if (layer->getFbo()) { - Caches::getInstance().fboCache.put(layer->getFbo()); + GLuint fbo = layer->getFbo(); + if (fbo) { + flushLayer(layer); + Caches::getInstance().fboCache.put(fbo); } if (!Caches::getInstance().layerCache.put(layer)) { @@ -331,6 +333,26 @@ void LayerRenderer::destroyLayerDeferred(Layer* layer) { } } +void LayerRenderer::flushLayer(Layer* layer) { +#ifdef GL_EXT_discard_framebuffer + GLuint fbo = layer->getFbo(); + if (layer && fbo) { + // If possible, discard any enqued operations on deferred + // rendering architectures + if (Caches::getInstance().extensions.hasDiscardFramebuffer()) { + GLuint previousFbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); + + GLenum attachments = GL_COLOR_ATTACHMENT0; + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments); + + glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); + } + } +#endif +} + bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) { Caches& caches = Caches::getInstance(); if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize && diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index 6104301..72d8d81 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -61,6 +61,7 @@ public: bool isOpaque, GLenum renderTarget, float* transform); ANDROID_API static void destroyLayer(Layer* layer); ANDROID_API static void destroyLayerDeferred(Layer* layer); + ANDROID_API static void flushLayer(Layer* layer); ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap); private: diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 70f1b7a..aa7d062 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -611,6 +611,11 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { } if (fboLayer) { + // Note: No need to use glDiscardFramebufferEXT() since we never + // create/compose layers that are not on screen with this + // code path + // See LayerRenderer::destroyLayer(Layer*) + // Detach the texture from the FBO glBindFramebuffer(GL_FRAMEBUFFER, current->fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 5bd0d4f..8c01e3a 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -61,6 +61,9 @@ enum DebugLevel { #define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size" #define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size" +// These properties are defined in percentage (range 0..1) +#define PROPERTY_TEXTURE_CACHE_FLUSH_RATE "ro.hwui.texture_cache_flush_rate" + // These properties are defined in pixels #define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width" #define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height" @@ -82,6 +85,8 @@ enum DebugLevel { #define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f #define DEFAULT_FBO_CACHE_SIZE 16 +#define DEFAULT_TEXTURE_CACHE_FLUSH_RATE 0.6f + #define DEFAULT_TEXT_GAMMA 1.4f #define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64 #define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192 diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index fbdbf92..018ce3e 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -34,7 +34,8 @@ namespace uirenderer { TextureCache::TextureCache(): mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity), - mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)) { + mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)), + mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) { char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) { INIT_LOGD(" Setting texture cache size to %sMB", property); @@ -43,6 +44,15 @@ TextureCache::TextureCache(): INIT_LOGD(" Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE); } + if (property_get(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, property, NULL) > 0) { + float flushRate = atof(property); + INIT_LOGD(" Setting texture cache flush rate to %.2f%%", flushRate * 100.0f); + setFlushRate(flushRate); + } else { + INIT_LOGD(" Using default texture cache flush rate of %.2f%%", + DEFAULT_TEXTURE_CACHE_FLUSH_RATE * 100.0f); + } + init(); } @@ -84,6 +94,10 @@ void TextureCache::setMaxSize(uint32_t maxSize) { } } +void TextureCache::setFlushRate(float flushRate) { + mFlushRate = fmaxf(0.0f, fminf(1.0f, flushRate)); +} + /////////////////////////////////////////////////////////////////////////////// // Callbacks /////////////////////////////////////////////////////////////////////////////// @@ -168,6 +182,21 @@ void TextureCache::clear() { TEXTURE_LOGD("TextureCache:clear(), mSize = %d", mSize); } +void TextureCache::flush() { + if (mFlushRate >= 1.0f || mCache.size() == 0) return; + if (mFlushRate <= 0.0f) { + clear(); + return; + } + + uint32_t targetSize = uint32_t(mSize * mFlushRate); + TEXTURE_LOGD("TextureCache::flush: target size: %d", targetSize); + + while (mSize > targetSize) { + mCache.removeOldest(); + } +} + void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) { SkAutoLockPixels alp(*bitmap); diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index f7707f7..ce924b4 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -98,6 +98,17 @@ public: */ uint32_t getSize(); + /** + * Partially flushes the cache. The amount of memory freed by a flush + * is defined by the flush rate. + */ + void flush(); + /** + * Indicates the percentage of the cache to retain when a + * memory trim is requested (see Caches::flush). + */ + void setFlushRate(float flushRate); + private: /** * Generates the texture from a bitmap into the specified texture structure. @@ -119,6 +130,8 @@ private: uint32_t mMaxSize; GLint mMaxTextureSize; + float mFlushRate; + bool mDebugEnabled; Vector<SkBitmap*> mGarbage; diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp index 93513fe..16446dd 100644 --- a/libs/rs/rsScript.cpp +++ b/libs/rs/rsScript.cpp @@ -15,6 +15,7 @@ */ #include "rsContext.h" +#include <time.h> using namespace android; using namespace android::renderscript; @@ -89,8 +90,22 @@ void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint3 } void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, size_t length) { - Script *s = static_cast<Script *>(vs); - s->mEnviroment.mTimeZone = timeZone; + // We unfortunately need to make a new copy of the string, since it is + // not NULL-terminated. We then use setenv(), which properly handles + // freeing/duplicating the actual string for the environment. + char *tz = (char *) malloc(length + 1); + if (!tz) { + LOGE("Couldn't allocate memory for timezone buffer"); + return; + } + strncpy(tz, timeZone, length); + tz[length] = '\0'; + if (setenv("TZ", tz, 1) == 0) { + tzset(); + } else { + LOGE("Error setting timezone"); + } + free(tz); } void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot, diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h index d645421..abb55b8 100644 --- a/libs/rs/rsScript.h +++ b/libs/rs/rsScript.h @@ -59,7 +59,6 @@ public: struct Enviroment_t { int64_t mStartTimeMillis; int64_t mLastDtTime; - const char* mTimeZone; ObjectBaseRef<ProgramVertex> mVertex; ObjectBaseRef<ProgramFragment> mFragment; diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp index d79a757..b4c581b 100644 --- a/libs/utils/CallStack.cpp +++ b/libs/utils/CallStack.cpp @@ -103,7 +103,7 @@ void CallStack::dump(const char* prefix) const { for (size_t i = 0; i < mCount; i++) { const backtrace_frame_t& frame = mStack[i]; const backtrace_symbol_t& symbol = symbols[i]; - const char* mapName = symbol.map_info ? symbol.map_info->name : "<unknown>"; + const char* mapName = symbol.map_name ? symbol.map_name : "<unknown>"; const char* symbolName = symbol.demangled_name ? symbol.demangled_name : symbol.name; if (symbolName) { LOGD("%s#%02d pc %08x %s (%s)\n", prefix, @@ -124,7 +124,7 @@ String8 CallStack::toString(const char* prefix) const { for (size_t i = 0; i < mCount; i++) { const backtrace_frame_t& frame = mStack[i]; const backtrace_symbol_t& symbol = symbols[i]; - const char* mapName = symbol.map_info ? symbol.map_info->name : "<unknown>"; + const char* mapName = symbol.map_name ? symbol.map_name : "<unknown>"; const char* symbolName = symbol.demangled_name ? symbol.demangled_name : symbol.name; if (symbolName) { str.appendFormat("%s#%02d pc %08x %s (%s)\n", prefix, |