OpenGLRenderer::drawText
OpenGLRenderer::drawTextのバックトレース
(gdb) b android::uirenderer::OpenGLRenderer::drawText Reading in symbols for frameworks/base/cmds/app_process/app_main.cpp...done. Reading in symbols for frameworks/base/libs/hwui/utils/Blur.cpp...done. Reading in symbols for frameworks/base/libs/hwui/OpenGLRenderer.cpp...done. Breakpoint 1 at 0x40b98cf0: file frameworks/base/libs/hwui/OpenGLRenderer.cpp, line 2921.
#0 android::uirenderer::OpenGLRenderer::drawText at frameworks/base/libs/hwui/OpenGLRenderer.cpp:2921 #1 android::uirenderer::DrawTextOp::multiDraw at frameworks/base/libs/hwui/DisplayListOp.h:1476 #2 android::uirenderer::MergingDrawBatch::replay at frameworks/base/libs/hwui/DeferredDisplayList.cpp:283 #3 replayBatchList at frameworks/base/libs/hwui/DeferredDisplayList.cpp:648 #4 android::uirenderer::DeferredDisplayList::flush at frameworks/base/libs/hwui/DeferredDisplayList.cpp:680 #5 android::uirenderer::OpenGLRenderer::drawDisplayList at frameworks/base/libs/hwui/OpenGLRenderer.cpp:2051 #6 android::android_view_GLES20Canvas_drawDisplayList at frameworks/base/core/jni/android_view_GLES20Canvas.cpp:778 #7 dvmPlatformInvoke () at dalvik/vm/arch/arm/CallEABI.S:258 #8 dvmCallJNIMethod at dalvik/vm/Jni.cpp:1159 #9 dalvik_mterp () at dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:16240 #10 dvmMterpStd at dalvik/vm/mterp/Mterp.cpp:105 #11 dvmInterpret at dalvik/vm/interp/Interp.cpp:1961 #12 dvmInvokeMethod at dalvik/vm/interp/Stack.cpp:737 #13 Dalvik_java_lang_reflect_Method_invokeNative at dalvik/vm/native/java_lang_reflect_Method.cpp:101 #14 dalvik_mterp () at dalvik/vm/mterp/out/InterpAsm-armv7-a-neon.S:16240 #15 dvmMterpStd at dalvik/vm/mterp/Mterp.cpp:105 #16 dvmInterpret at dalvik/vm/interp/Interp.cpp:1961 #17 dvmCallMethodV at dalvik/vm/interp/Stack.cpp:526 #18 CallStaticVoidMethodV at libnativehelper/include/nativehelper/jni.h:780 #20 android::AndroidRuntime::start at frameworks/base/core/jni/AndroidRuntime.cpp:887 #21 main at frameworks/base/cmds/app_process/app_main.cpp:231
2919 status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, 2920 const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds, 2921 DrawOpMode drawOpMode) { 2922 2923 if (drawOpMode == kDrawOpMode_Immediate) { 2924 // The checks for corner-case ignorable text and quick rejection is only done for immediate 2925 // drawing as ops from DeferredDisplayList are already filtered for these 2926 if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint) || 2927 quickReject(bounds)) { 2928 return DrawGlInfo::kStatusDone; 2929 } 2930 } 2931 2932 const float oldX = x; 2933 const float oldY = y; 2934 2935 const mat4& transform = currentTransform(); 2936 const bool pureTranslate = transform.isPureTranslate(); 2937 2938 if (CC_LIKELY(pureTranslate)) { 2939 x = (int) floorf(x + transform.getTranslateX() + 0.5f); 2940 y = (int) floorf(y + transform.getTranslateY() + 0.5f); 2941 } 2942 2943 int alpha; 2944 SkXfermode::Mode mode; 2945 getAlphaAndMode(paint, &alpha, &mode); 2946 2947 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); 2948 2949 if (CC_UNLIKELY(mDrawModifiers.mHasShadow)) { 2950 fontRenderer.setFont(paint, mat4::identity()); 2951 drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, 2952 alpha, mode, oldX, oldY); 2953 } 2954 2955 const bool hasActiveLayer = hasLayer(); 2956 2957 // We only pass a partial transform to the font renderer. That partial 2958 // matrix defines how glyphs are rasterized. Typically we want glyphs 2959 // to be rasterized at their final size on screen, which means the partial 2960 // matrix needs to take the scale factor into account. 2961 // When a partial matrix is used to transform glyphs during rasterization, 2962 // the mesh is generated with the inverse transform (in the case of scale, 2963 // the mesh is generated at 1.0 / scale for instance.) This allows us to 2964 // apply the full transform matrix at draw time in the vertex shader. 2965 // Applying the full matrix in the shader is the easiest way to handle 2966 // rotation and perspective and allows us to always generated quads in the 2967 // font renderer which greatly simplifies the code, clipping in particular. 2968 mat4 fontTransform = findBestFontTransform(transform); 2969 fontRenderer.setFont(paint, fontTransform); 2970 2971 // Pick the appropriate texture filtering 2972 bool linearFilter = !pureTranslate || fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f; 2973 fontRenderer.setTextureFiltering(linearFilter); 2974 2975 // TODO: Implement better clipping for scaled/rotated text 2976 const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect; 2977 Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); 2978 2979 bool status; 2980 TextSetupFunctor functor(this, x, y, pureTranslate, alpha, mode, paint); 2981 2982 // don't call issuedrawcommand, do it at end of batch 2983 bool forceFinish = (drawOpMode != kDrawOpMode_Defer); 2984 if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) { 2985 SkPaint paintCopy(*paint); 2986 paintCopy.setTextAlign(SkPaint::kLeft_Align); 2987 status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y, 2988 positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish); 2989 } else { 2990 status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, 2991 positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish); 2992 } 2993 2994 if ((status || drawOpMode != kDrawOpMode_Immediate) && hasActiveLayer) { 2995 if (!pureTranslate) { 2996 transform.mapRect(layerBounds); 2997 } 2998 dirtyLayerUnchecked(layerBounds, getRegion()); 2999 } 3000 3001 drawTextDecorations(text, bytesCount, totalAdvance, oldX, oldY, paint); 3002 3003 return DrawGlInfo::kStatusDrew; 3004 }