/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "OpenGLRenderer" #include "DisplayListRenderer.h" namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Display list /////////////////////////////////////////////////////////////////////////////// const char* DisplayList::OP_NAMES[] = { "Save", "Restore", "RestoreToCount", "SaveLayer", "SaveLayerAlpha", "Translate", "Rotate", "Scale", "Skew", "SetMatrix", "ConcatMatrix", "ClipRect", "DrawDisplayList", "DrawLayer", "DrawBitmap", "DrawBitmapMatrix", "DrawBitmapRect", "DrawBitmapMesh", "DrawPatch", "DrawColor", "DrawRect", "DrawRoundRect", "DrawCircle", "DrawOval", "DrawArc", "DrawPath", "DrawLines", "DrawText", "ResetShader", "SetupShader", "ResetColorFilter", "SetupColorFilter", "ResetShadow", "SetupShadow", "DrawGLFunction" }; DisplayList::DisplayList(const DisplayListRenderer& recorder) { initFromDisplayListRenderer(recorder); } DisplayList::~DisplayList() { clearResources(); } void DisplayList::clearResources() { sk_free((void*) mReader.base()); Caches& caches = Caches::getInstance(); for (size_t i = 0; i < mBitmapResources.size(); i++) { caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); } mBitmapResources.clear(); for (size_t i = 0; i < mShaders.size(); i++) { caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); } mShaders.clear(); for (size_t i = 0; i < mPaints.size(); i++) { delete mPaints.itemAt(i); } mPaints.clear(); for (size_t i = 0; i < mPaths.size(); i++) { delete mPaths.itemAt(i); } mPaths.clear(); for (size_t i = 0; i < mOriginalPaths.size(); i++) { caches.resourceCache.decrementRefcount(mOriginalPaths.itemAt(i)); } mOriginalPaths.clear(); for (size_t i = 0; i < mMatrices.size(); i++) { delete mMatrices.itemAt(i); } mMatrices.clear(); } void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) { const SkWriter32& writer = recorder.writeStream(); init(); if (writer.size() == 0) { return; } if (reusing) { // re-using display list - clear out previous allocations clearResources(); } size_t size = writer.size(); void* buffer = sk_malloc_throw(size); writer.flatten(buffer); mReader.setMemory(buffer, size); Caches& caches = Caches::getInstance(); const Vector &bitmapResources = recorder.getBitmapResources(); for (size_t i = 0; i < bitmapResources.size(); i++) { SkBitmap* resource = bitmapResources.itemAt(i); mBitmapResources.add(resource); caches.resourceCache.incrementRefcount(resource); } const Vector &shaders = recorder.getShaders(); for (size_t i = 0; i < shaders.size(); i++) { SkiaShader* shader = shaders.itemAt(i); mShaders.add(shader); caches.resourceCache.incrementRefcount(shader); } const Vector &paints = recorder.getPaints(); for (size_t i = 0; i < paints.size(); i++) { mPaints.add(paints.itemAt(i)); } const Vector &paths = recorder.getPaths(); for (size_t i = 0; i < paths.size(); i++) { mPaths.add(paths.itemAt(i)); } const Vector &originalPaths = recorder.getOriginalPaths(); for (size_t i = 0; i < originalPaths.size(); i++) { SkPath* path = originalPaths.itemAt(i); mOriginalPaths.add(path); caches.resourceCache.incrementRefcount(path); } const Vector &matrices = recorder.getMatrices(); for (size_t i = 0; i < matrices.size(); i++) { mMatrices.add(matrices.itemAt(i)); } } void DisplayList::init() { } bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) { bool needsInvalidate = false; TextContainer text; mReader.rewind(); #if DEBUG_DISPLAY_LIST uint32_t count = (level + 1) * 2; char indent[count + 1]; for (uint32_t i = 0; i < count; i++) { indent[i] = ' '; } indent[count] = '\0'; DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this); #endif int saveCount = renderer.getSaveCount() - 1; while (!mReader.eof()) { int op = mReader.readInt(); switch (op) { case DrawGLFunction: { Functor *functor = (Functor *) getInt(); DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor); needsInvalidate |= renderer.callDrawGLFunction(functor, dirty); } break; case Save: { int rendererNum = getInt(); DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum); renderer.save(rendererNum); } break; case Restore: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.restore(); } break; case RestoreToCount: { int restoreCount = saveCount + getInt(); DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount); renderer.restoreToCount(restoreCount); } break; case SaveLayer: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); SkPaint* paint = getPaint(); int flags = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint, flags); renderer.saveLayer(f1, f2, f3, f4, paint, flags); } break; case SaveLayerAlpha: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); int alpha = getInt(); int flags = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, alpha, flags); renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags); } break; case Translate: { float f1 = getFloat(); float f2 = getFloat(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2); renderer.translate(f1, f2); } break; case Rotate: { float rotation = getFloat(); DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation); renderer.rotate(rotation); } break; case Scale: { float sx = getFloat(); float sy = getFloat(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); renderer.scale(sx, sy); } break; case Skew: { float sx = getFloat(); float sy = getFloat(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); renderer.skew(sx, sy); } break; case SetMatrix: { SkMatrix* matrix = getMatrix(); DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix); renderer.setMatrix(matrix); } break; case ConcatMatrix: { SkMatrix* matrix = getMatrix(); DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix); renderer.concatMatrix(matrix); } break; case ClipRect: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); int regionOp = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, regionOp); renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp); } break; case DrawDisplayList: { DisplayList* displayList = getDisplayList(); uint32_t width = getUInt(); uint32_t height = getUInt(); DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op], displayList, width, height, level + 1); needsInvalidate |= renderer.drawDisplayList(displayList, width, height, dirty, level + 1); } break; case DrawLayer: { Layer* layer = (Layer*) getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], layer, x, y, paint); renderer.drawLayer(layer, x, y, paint); } break; case DrawBitmap: { SkBitmap* bitmap = getBitmap(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], bitmap, x, y, paint); renderer.drawBitmap(bitmap, x, y, paint); } break; case DrawBitmapMatrix: { SkBitmap* bitmap = getBitmap(); SkMatrix* matrix = getMatrix(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op], bitmap, matrix, paint); renderer.drawBitmap(bitmap, matrix, paint); } break; case DrawBitmapRect: { SkBitmap* bitmap = getBitmap(); float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); float f5 = getFloat(); float f6 = getFloat(); float f7 = getFloat(); float f8 = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); } break; case DrawBitmapMesh: { int verticesCount = 0; uint32_t colorsCount = 0; SkBitmap* bitmap = getBitmap(); uint32_t meshWidth = getInt(); uint32_t meshHeight = getInt(); float* vertices = getFloats(verticesCount); bool hasColors = getInt(); int* colors = hasColors ? getInts(colorsCount) : NULL; DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint()); } break; case DrawPatch: { int32_t* xDivs = NULL; int32_t* yDivs = NULL; uint32_t* colors = NULL; uint32_t xDivsCount = 0; uint32_t yDivsCount = 0; int8_t numColors = 0; SkBitmap* bitmap = getBitmap(); xDivs = getInts(xDivsCount); yDivs = getInts(yDivsCount); colors = getUInts(numColors); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount, numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint()); } break; case DrawColor: { int color = getInt(); int xferMode = getInt(); DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode); renderer.drawColor(color, (SkXfermode::Mode) xferMode); } break; case DrawRect: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); renderer.drawRect(f1, f2, f3, f4, paint); } break; case DrawRoundRect: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); float f5 = getFloat(); float f6 = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint); renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint); } break; case DrawCircle: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, paint); renderer.drawCircle(f1, f2, f3, paint); } break; case DrawOval: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); renderer.drawOval(f1, f2, f3, f4, paint); } break; case DrawArc: { float f1 = getFloat(); float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); float f5 = getFloat(); float f6 = getFloat(); int i1 = getInt(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint); renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint); } break; case DrawPath: { SkPath* path = getPath(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint); renderer.drawPath(path, paint); } break; case DrawLines: { int count = 0; float* points = getFloats(count); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.drawLines(points, count, getPaint()); } break; case DrawText: { getText(&text); int count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], text.text(), text.length(), count, x, y, paint); renderer.drawText(text.text(), text.length(), count, x, y, paint); } break; case ResetShader: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.resetShader(); } break; case SetupShader: { SkiaShader* shader = getShader(); DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader); renderer.setupShader(shader); } break; case ResetColorFilter: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.resetColorFilter(); } break; case SetupColorFilter: { SkiaColorFilter *colorFilter = getColorFilter(); DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter); renderer.setupColorFilter(colorFilter); } break; case ResetShadow: { DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); renderer.resetShadow(); } break; case SetupShadow: { float radius = getFloat(); float dx = getFloat(); float dy = getFloat(); int color = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op], radius, dx, dy, color); renderer.setupShadow(radius, dx, dy, color); } break; default: DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s", (char*) indent, OP_NAMES[op]); break; } } DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate); return needsInvalidate; } /////////////////////////////////////////////////////////////////////////////// // Base structure /////////////////////////////////////////////////////////////////////////////// DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) { mDisplayList = NULL; } DisplayListRenderer::~DisplayListRenderer() { reset(); } void DisplayListRenderer::reset() { mWriter.reset(); Caches& caches = Caches::getInstance(); for (size_t i = 0; i < mBitmapResources.size(); i++) { SkBitmap* resource = mBitmapResources.itemAt(i); caches.resourceCache.decrementRefcount(resource); } mBitmapResources.clear(); for (size_t i = 0; i < mOriginalPaths.size(); i++) { SkPath* resource = mOriginalPaths.itemAt(i); caches.resourceCache.decrementRefcount(resource); } mOriginalPaths.clear(); for (size_t i = 0; i < mShaders.size(); i++) { caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); } mShaders.clear(); mShaderMap.clear(); mPaints.clear(); mPaintMap.clear(); mPaths.clear(); mPathMap.clear(); mMatrices.clear(); } /////////////////////////////////////////////////////////////////////////////// // Operations /////////////////////////////////////////////////////////////////////////////// DisplayList* DisplayListRenderer::getDisplayList() { if (mDisplayList == NULL) { mDisplayList = new DisplayList(*this); } else { mDisplayList->initFromDisplayListRenderer(*this, true); } return mDisplayList; } void DisplayListRenderer::setViewport(int width, int height) { mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); mWidth = width; mHeight = height; } void DisplayListRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { mSnapshot = new Snapshot(mFirstSnapshot, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); mSaveCount = 1; mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); mRestoreSaveCount = -1; } void DisplayListRenderer::finish() { insertRestoreToCount(); OpenGLRenderer::finish(); } void DisplayListRenderer::interrupt() { } void DisplayListRenderer::resume() { } bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { // Ignore dirty during recording, it matters only when we replay addOp(DisplayList::DrawGLFunction); addInt((int) functor); return false; // No invalidate needed at record-time } int DisplayListRenderer::save(int flags) { addOp(DisplayList::Save); addInt(flags); return OpenGLRenderer::save(flags); } void DisplayListRenderer::restore() { addOp(DisplayList::Restore); OpenGLRenderer::restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; OpenGLRenderer::restoreToCount(saveCount); } int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, SkPaint* p, int flags) { addOp(DisplayList::SaveLayer); addBounds(left, top, right, bottom); addPaint(p); addInt(flags); return OpenGLRenderer::save(flags); } int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int flags) { addOp(DisplayList::SaveLayerAlpha); addBounds(left, top, right, bottom); addInt(alpha); addInt(flags); return OpenGLRenderer::save(flags); } void DisplayListRenderer::translate(float dx, float dy) { addOp(DisplayList::Translate); addPoint(dx, dy); OpenGLRenderer::translate(dx, dy); } void DisplayListRenderer::rotate(float degrees) { addOp(DisplayList::Rotate); addFloat(degrees); OpenGLRenderer::rotate(degrees); } void DisplayListRenderer::scale(float sx, float sy) { addOp(DisplayList::Scale); addPoint(sx, sy); OpenGLRenderer::scale(sx, sy); } void DisplayListRenderer::skew(float sx, float sy) { addOp(DisplayList::Skew); addPoint(sx, sy); OpenGLRenderer::skew(sx, sy); } void DisplayListRenderer::setMatrix(SkMatrix* matrix) { addOp(DisplayList::SetMatrix); addMatrix(matrix); OpenGLRenderer::setMatrix(matrix); } void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { addOp(DisplayList::ConcatMatrix); addMatrix(matrix); OpenGLRenderer::concatMatrix(matrix); } bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { addOp(DisplayList::ClipRect); addBounds(left, top, right, bottom); addInt(op); return OpenGLRenderer::clipRect(left, top, right, bottom, op); } bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height, Rect& dirty, uint32_t level) { // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list addOp(DisplayList::DrawDisplayList); addDisplayList(displayList); addSize(width, height); return false; } void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { addOp(DisplayList::DrawLayer); addInt((int) layer); addPoint(x, y); addPaint(paint); } void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { addOp(DisplayList::DrawBitmap); addBitmap(bitmap); addPoint(left, top); addPaint(paint); } void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { addOp(DisplayList::DrawBitmapMatrix); addBitmap(bitmap); addMatrix(matrix); addPaint(paint); } void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { addOp(DisplayList::DrawBitmapRect); addBitmap(bitmap); addBounds(srcLeft, srcTop, srcRight, srcBottom); addBounds(dstLeft, dstTop, dstRight, dstBottom); addPaint(paint); } void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint) { addOp(DisplayList::DrawBitmapMesh); addBitmap(bitmap); addInt(meshWidth); addInt(meshHeight); addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2); if (colors) { addInt(1); addInts(colors, (meshWidth + 1) * (meshHeight + 1)); } else { addInt(0); } addPaint(paint); } void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) { addOp(DisplayList::DrawPatch); addBitmap(bitmap); addInts(xDivs, width); addInts(yDivs, height); addUInts(colors, numColors); addBounds(left, top, right, bottom); addPaint(paint); } void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { addOp(DisplayList::DrawColor); addInt(color); addInt(mode); } void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { addOp(DisplayList::DrawRect); addBounds(left, top, right, bottom); addPaint(paint); } void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* paint) { addOp(DisplayList::DrawRoundRect); addBounds(left, top, right, bottom); addPoint(rx, ry); addPaint(paint); } void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { addOp(DisplayList::DrawCircle); addPoint(x, y); addFloat(radius); addPaint(paint); } void DisplayListRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) { addOp(DisplayList::DrawOval); addBounds(left, top, right, bottom); addPaint(paint); } void DisplayListRenderer::drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { addOp(DisplayList::DrawArc); addBounds(left, top, right, bottom); addPoint(startAngle, sweepAngle); addInt(useCenter ? 1 : 0); addPaint(paint); } void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { addOp(DisplayList::DrawPath); addPath(path); addPaint(paint); } void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { addOp(DisplayList::DrawLines); addFloats(points, count); addPaint(paint); } void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint) { addOp(DisplayList::DrawText); addText(text, bytesCount); addInt(count); addPoint(x, y); addPaint(paint); } void DisplayListRenderer::resetShader() { addOp(DisplayList::ResetShader); } void DisplayListRenderer::setupShader(SkiaShader* shader) { addOp(DisplayList::SetupShader); addShader(shader); } void DisplayListRenderer::resetColorFilter() { addOp(DisplayList::ResetColorFilter); } void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { addOp(DisplayList::SetupColorFilter); addColorFilter(filter); } void DisplayListRenderer::resetShadow() { addOp(DisplayList::ResetShadow); } void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { addOp(DisplayList::SetupShadow); addFloat(radius); addPoint(dx, dy); addInt(color); } }; // namespace uirenderer }; // namespace android