Loading core/jni/android_view_GLES20Canvas.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -528,8 +528,11 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, } const jchar* glyphs = value->getGlyphs(); size_t glyphsCount = value->getGlyphsCount(); jfloat totalAdvance = value->getTotalAdvance(); const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); renderer->drawGeneralText((const char*) glyphs, bytesCount, glyphsCount, x, y, positions, paint, totalAdvance); } static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count, Loading @@ -556,8 +559,11 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, } const jchar* glyphs = value->getGlyphs(); size_t glyphsCount = value->getGlyphsCount(); jfloat totalAdvance = value->getTotalAdvance(); const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); renderer->drawGeneralText((const char*) glyphs, bytesCount, glyphsCount, x, y, positions, paint, totalAdvance); } static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, Loading libs/hwui/DisplayListRenderer.cpp +59 −55 Original line number Diff line number Diff line Loading @@ -61,9 +61,9 @@ const char* DisplayList::OP_NAMES[] = { "DrawPath", "DrawLines", "DrawPoints", "DrawText", "DrawTextOnPath", "DrawPosText", "DrawGeneralText", "ResetShader", "SetupShader", "ResetColorFilter", Loading Loading @@ -572,17 +572,6 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { ALOGD("%s%s", (char*) indent, OP_NAMES[op]); } break; case DrawText: { getText(&text); int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); float length = getFloat(); ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); } break; case DrawTextOnPath: { getText(&text); int32_t count = getInt(); Loading @@ -603,6 +592,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); } break; case DrawGeneralText: { getText(&text); int count = getInt(); int positionsCount = 0; float* positions = getFloats(positionsCount); SkPaint* paint = getPaint(renderer); ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); } break; case ResetShader: { ALOGD("%s%s", (char*) indent, OP_NAMES[op]); } Loading Loading @@ -1196,19 +1196,6 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag drawGlStatus |= renderer.drawPoints(points, count, paint); } break; case DrawText: { getText(&text); int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); float length = getFloat(); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y, paint, length); } break; case DrawTextOnPath: { getText(&text); int32_t count = getInt(); Loading @@ -1234,6 +1221,21 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag positions, paint); } break; case DrawGeneralText: { getText(&text); int32_t count = getInt(); float x = getFloat(); float y = getFloat(); int32_t positionsCount = 0; float* positions = getFloats(positionsCount); SkPaint* paint = getPaint(renderer); float length = getFloat(); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); drawGlStatus |= renderer.drawGeneralText(text.text(), text.length(), count, x, y, positions, paint, length); } break; case ResetShader: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.resetShader(); Loading Loading @@ -1684,8 +1686,34 @@ status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* pain return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawTextOnPath); addText(text, bytesCount); addInt(count); addPath(path); addFloat(hOffset); addFloat(vOffset); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawPosText); addText(text, bytesCount); addInt(count); addFloats(positions, count * 2); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; // TODO: We should probably make a copy of the paint instead of modifying Loading @@ -1705,42 +1733,18 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom); } uint32_t* location = addOp(DisplayList::DrawText, reject); uint32_t* location = addOp(DisplayList::DrawGeneralText, reject); addText(text, bytesCount); addInt(count); addPoint(x, y); addFloat(x); addFloat(y); addFloats(positions, count * 2); addPaint(paint); addFloat(length); addSkip(location); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawTextOnPath); addText(text, bytesCount); addInt(count); addPath(path); addFloat(hOffset); addFloat(vOffset); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawPosText); addText(text, bytesCount); addInt(count); addFloats(positions, count * 2); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } void DisplayListRenderer::resetShader() { addOp(DisplayList::ResetShader); } Loading libs/hwui/DisplayListRenderer.h +3 −3 Original line number Diff line number Diff line Loading @@ -103,9 +103,9 @@ public: DrawPath, DrawLines, DrawPoints, DrawText, DrawTextOnPath, DrawPosText, DrawGeneralText, ResetShader, SetupShader, ResetColorFilter, Loading Loading @@ -599,12 +599,12 @@ public: virtual status_t drawPath(SkPath* path, SkPaint* paint); virtual status_t drawLines(float* points, int count, SkPaint* paint); virtual status_t drawPoints(float* points, int count, SkPaint* paint); virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); virtual status_t drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); Loading libs/hwui/OpenGLRenderer.cpp +16 −6 Original line number Diff line number Diff line Loading @@ -2421,8 +2421,8 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count return DrawGlInfo::kStatusDrew; } status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { status_t OpenGLRenderer::drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || (paint->getAlpha() * mSnapshot->alpha == 0 && paint->getXfermode() == NULL)) { return DrawGlInfo::kStatusDone; Loading Loading @@ -2455,7 +2455,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } #if DEBUG_GLYPHS ALOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface())); ALOGD("OpenGLRenderer drawGeneralText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface())); #endif FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); Loading @@ -2467,7 +2468,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, getAlphaAndMode(paint, &alpha, &mode); if (CC_UNLIKELY(mHasShadow)) { drawTextShadow(paint, text, bytesCount, count, NULL, fontRenderer, alpha, mode, oldX, oldY); drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode, oldX, oldY); } // Pick the appropriate texture filtering Loading Loading @@ -2505,8 +2507,16 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, const bool hasActiveLayer = false; #endif if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, hasActiveLayer ? &bounds : NULL)) { bool status; if (positions != NULL) { status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, positions, hasActiveLayer ? &bounds : NULL); } else { // TODO: would it be okay to call renderPosText with null positions? status = fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, hasActiveLayer ? &bounds : NULL); } if (status) { #if RENDER_LAYERS_AS_REGIONS if (hasActiveLayer) { if (!pureTranslate) { Loading libs/hwui/OpenGLRenderer.h +2 −2 Original line number Diff line number Diff line Loading @@ -138,12 +138,12 @@ public: virtual status_t drawPath(SkPath* path, SkPaint* paint); virtual status_t drawLines(float* points, int count, SkPaint* paint); virtual status_t drawPoints(float* points, int count, SkPaint* paint); virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); virtual status_t drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length = -1.0f); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); Loading Loading
core/jni/android_view_GLES20Canvas.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -528,8 +528,11 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, } const jchar* glyphs = value->getGlyphs(); size_t glyphsCount = value->getGlyphsCount(); jfloat totalAdvance = value->getTotalAdvance(); const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); renderer->drawGeneralText((const char*) glyphs, bytesCount, glyphsCount, x, y, positions, paint, totalAdvance); } static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count, Loading @@ -556,8 +559,11 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, } const jchar* glyphs = value->getGlyphs(); size_t glyphsCount = value->getGlyphsCount(); jfloat totalAdvance = value->getTotalAdvance(); const float* positions = value->getPos(); int bytesCount = glyphsCount * sizeof(jchar); renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); renderer->drawGeneralText((const char*) glyphs, bytesCount, glyphsCount, x, y, positions, paint, totalAdvance); } static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, Loading
libs/hwui/DisplayListRenderer.cpp +59 −55 Original line number Diff line number Diff line Loading @@ -61,9 +61,9 @@ const char* DisplayList::OP_NAMES[] = { "DrawPath", "DrawLines", "DrawPoints", "DrawText", "DrawTextOnPath", "DrawPosText", "DrawGeneralText", "ResetShader", "SetupShader", "ResetColorFilter", Loading Loading @@ -572,17 +572,6 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { ALOGD("%s%s", (char*) indent, OP_NAMES[op]); } break; case DrawText: { getText(&text); int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); float length = getFloat(); ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); } break; case DrawTextOnPath: { getText(&text); int32_t count = getInt(); Loading @@ -603,6 +592,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); } break; case DrawGeneralText: { getText(&text); int count = getInt(); int positionsCount = 0; float* positions = getFloats(positionsCount); SkPaint* paint = getPaint(renderer); ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, paint); } break; case ResetShader: { ALOGD("%s%s", (char*) indent, OP_NAMES[op]); } Loading Loading @@ -1196,19 +1196,6 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag drawGlStatus |= renderer.drawPoints(points, count, paint); } break; case DrawText: { getText(&text); int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); float length = getFloat(); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y, paint, length); } break; case DrawTextOnPath: { getText(&text); int32_t count = getInt(); Loading @@ -1234,6 +1221,21 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag positions, paint); } break; case DrawGeneralText: { getText(&text); int32_t count = getInt(); float x = getFloat(); float y = getFloat(); int32_t positionsCount = 0; float* positions = getFloats(positionsCount); SkPaint* paint = getPaint(renderer); float length = getFloat(); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); drawGlStatus |= renderer.drawGeneralText(text.text(), text.length(), count, x, y, positions, paint, length); } break; case ResetShader: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.resetShader(); Loading Loading @@ -1684,8 +1686,34 @@ status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* pain return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawTextOnPath); addText(text, bytesCount); addInt(count); addPath(path); addFloat(hOffset); addFloat(vOffset); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawPosText); addText(text, bytesCount); addInt(count); addFloats(positions, count * 2); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; // TODO: We should probably make a copy of the paint instead of modifying Loading @@ -1705,42 +1733,18 @@ status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int cou reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom); } uint32_t* location = addOp(DisplayList::DrawText, reject); uint32_t* location = addOp(DisplayList::DrawGeneralText, reject); addText(text, bytesCount); addInt(count); addPoint(x, y); addFloat(x); addFloat(y); addFloats(positions, count * 2); addPaint(paint); addFloat(length); addSkip(location); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawTextOnPath); addText(text, bytesCount); addInt(count); addPath(path); addFloat(hOffset); addFloat(vOffset); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (!text || count <= 0) return DrawGlInfo::kStatusDone; addOp(DisplayList::DrawPosText); addText(text, bytesCount); addInt(count); addFloats(positions, count * 2); paint->setAntiAlias(true); addPaint(paint); return DrawGlInfo::kStatusDone; } void DisplayListRenderer::resetShader() { addOp(DisplayList::ResetShader); } Loading
libs/hwui/DisplayListRenderer.h +3 −3 Original line number Diff line number Diff line Loading @@ -103,9 +103,9 @@ public: DrawPath, DrawLines, DrawPoints, DrawText, DrawTextOnPath, DrawPosText, DrawGeneralText, ResetShader, SetupShader, ResetColorFilter, Loading Loading @@ -599,12 +599,12 @@ public: virtual status_t drawPath(SkPath* path, SkPaint* paint); virtual status_t drawLines(float* points, int count, SkPaint* paint); virtual status_t drawPoints(float* points, int count, SkPaint* paint); virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); virtual status_t drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); Loading
libs/hwui/OpenGLRenderer.cpp +16 −6 Original line number Diff line number Diff line Loading @@ -2421,8 +2421,8 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count return DrawGlInfo::kStatusDrew; } status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { status_t OpenGLRenderer::drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length) { if (text == NULL || count == 0 || mSnapshot->isIgnored() || (paint->getAlpha() * mSnapshot->alpha == 0 && paint->getXfermode() == NULL)) { return DrawGlInfo::kStatusDone; Loading Loading @@ -2455,7 +2455,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, } #if DEBUG_GLYPHS ALOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface())); ALOGD("OpenGLRenderer drawGeneralText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface())); #endif FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); Loading @@ -2467,7 +2468,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, getAlphaAndMode(paint, &alpha, &mode); if (CC_UNLIKELY(mHasShadow)) { drawTextShadow(paint, text, bytesCount, count, NULL, fontRenderer, alpha, mode, oldX, oldY); drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode, oldX, oldY); } // Pick the appropriate texture filtering Loading Loading @@ -2505,8 +2507,16 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, const bool hasActiveLayer = false; #endif if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, hasActiveLayer ? &bounds : NULL)) { bool status; if (positions != NULL) { status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y, positions, hasActiveLayer ? &bounds : NULL); } else { // TODO: would it be okay to call renderPosText with null positions? status = fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, hasActiveLayer ? &bounds : NULL); } if (status) { #if RENDER_LAYERS_AS_REGIONS if (hasActiveLayer) { if (!pureTranslate) { Loading
libs/hwui/OpenGLRenderer.h +2 −2 Original line number Diff line number Diff line Loading @@ -138,12 +138,12 @@ public: virtual status_t drawPath(SkPath* path, SkPaint* paint); virtual status_t drawLines(float* points, int count, SkPaint* paint); virtual status_t drawPoints(float* points, int count, SkPaint* paint); virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, float hOffset, float vOffset, SkPaint* paint); virtual status_t drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); virtual status_t drawGeneralText(const char* text, int bytesCount, int count, float x, float y, const float* positions, SkPaint* paint, float length = -1.0f); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); Loading