DisplayListRenderer.cpp revision d490aa426090fc358873821b47ef27ead0c97409
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "OpenGLRenderer" 18 19#include <SkCamera.h> 20#include <SkCanvas.h> 21 22#include <private/hwui/DrawGlInfo.h> 23 24#include "Caches.h" 25#include "DeferredDisplayList.h" 26#include "DisplayListLogBuffer.h" 27#include "DisplayListOp.h" 28#include "DisplayListRenderer.h" 29#include "RenderNode.h" 30 31namespace android { 32namespace uirenderer { 33 34DisplayListRenderer::DisplayListRenderer(): 35 mCaches(Caches::getInstance()), mDisplayListData(0), 36 mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), 37 mRestoreSaveCount(-1) { 38} 39 40DisplayListRenderer::~DisplayListRenderer() { 41 LOG_ALWAYS_FATAL_IF(mDisplayListData, 42 "Destroyed a DisplayListRenderer during a record!"); 43} 44 45/////////////////////////////////////////////////////////////////////////////// 46// Operations 47/////////////////////////////////////////////////////////////////////////////// 48 49DisplayListData* DisplayListRenderer::finishRecording() { 50 mPaintMap.clear(); 51 mRegionMap.clear(); 52 mPathMap.clear(); 53 DisplayListData* data = mDisplayListData; 54 mDisplayListData = 0; 55 return data; 56} 57 58status_t DisplayListRenderer::prepareDirty(float left, float top, 59 float right, float bottom, bool opaque) { 60 61 LOG_ALWAYS_FATAL_IF(mDisplayListData, 62 "prepareDirty called a second time during a recording!"); 63 mDisplayListData = new DisplayListData(); 64 65 initializeSaveStack(0, 0, getWidth(), getHeight()); 66 67 mDirtyClip = opaque; 68 mRestoreSaveCount = -1; 69 70 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 71} 72 73void DisplayListRenderer::finish() { 74 insertRestoreToCount(); 75 insertTranslate(); 76} 77 78void DisplayListRenderer::interrupt() { 79} 80 81void DisplayListRenderer::resume() { 82} 83 84status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { 85 // Ignore dirty during recording, it matters only when we replay 86 addDrawOp(new (alloc()) DrawFunctorOp(functor)); 87 mDisplayListData->functorCount++; 88 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 89} 90 91int DisplayListRenderer::save(int flags) { 92 addStateOp(new (alloc()) SaveOp(flags)); 93 return StatefulBaseRenderer::save(flags); 94} 95 96void DisplayListRenderer::restore() { 97 if (mRestoreSaveCount < 0) { 98 restoreToCount(getSaveCount() - 1); 99 return; 100 } 101 102 mRestoreSaveCount--; 103 insertTranslate(); 104 StatefulBaseRenderer::restore(); 105} 106 107void DisplayListRenderer::restoreToCount(int saveCount) { 108 mRestoreSaveCount = saveCount; 109 insertTranslate(); 110 StatefulBaseRenderer::restoreToCount(saveCount); 111} 112 113int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 114 const SkPaint* paint, int flags) { 115 paint = refPaint(paint); 116 addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); 117 return StatefulBaseRenderer::save(flags); 118} 119 120void DisplayListRenderer::translate(float dx, float dy, float dz) { 121 // ignore dz, not used at defer time 122 mHasTranslate = true; 123 mTranslateX += dx; 124 mTranslateY += dy; 125 insertRestoreToCount(); 126 StatefulBaseRenderer::translate(dx, dy, dz); 127} 128 129void DisplayListRenderer::rotate(float degrees) { 130 addStateOp(new (alloc()) RotateOp(degrees)); 131 StatefulBaseRenderer::rotate(degrees); 132} 133 134void DisplayListRenderer::scale(float sx, float sy) { 135 addStateOp(new (alloc()) ScaleOp(sx, sy)); 136 StatefulBaseRenderer::scale(sx, sy); 137} 138 139void DisplayListRenderer::skew(float sx, float sy) { 140 addStateOp(new (alloc()) SkewOp(sx, sy)); 141 StatefulBaseRenderer::skew(sx, sy); 142} 143 144void DisplayListRenderer::setMatrix(const SkMatrix* matrix) { 145 matrix = refMatrix(matrix); 146 addStateOp(new (alloc()) SetMatrixOp(matrix)); 147 StatefulBaseRenderer::setMatrix(matrix); 148} 149 150void DisplayListRenderer::concatMatrix(const SkMatrix* matrix) { 151 matrix = refMatrix(matrix); 152 addStateOp(new (alloc()) ConcatMatrixOp(matrix)); 153 StatefulBaseRenderer::concatMatrix(matrix); 154} 155 156bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 157 SkRegion::Op op) { 158 addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); 159 return StatefulBaseRenderer::clipRect(left, top, right, bottom, op); 160} 161 162bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) { 163 path = refPath(path); 164 addStateOp(new (alloc()) ClipPathOp(path, op)); 165 return StatefulBaseRenderer::clipPath(path, op); 166} 167 168bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { 169 region = refRegion(region); 170 addStateOp(new (alloc()) ClipRegionOp(region, op)); 171 return StatefulBaseRenderer::clipRegion(region, op); 172} 173 174status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList, 175 Rect& dirty, int32_t flags) { 176 // dirty is an out parameter and should not be recorded, 177 // it matters only when replaying the display list 178 179 if (displayList->stagingProperties().isProjectionReceiver()) { 180 // use staging property, since recording on UI thread 181 mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size(); 182 } 183 184 DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList, 185 flags, *currentTransform()); 186 addDrawOp(op); 187 mDisplayListData->addChild(op); 188 return DrawGlInfo::kStatusDone; 189} 190 191status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) { 192 layer = refLayer(layer); 193 addDrawOp(new (alloc()) DrawLayerOp(layer, x, y)); 194 return DrawGlInfo::kStatusDone; 195} 196 197status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top, 198 const SkPaint* paint) { 199 bitmap = refBitmap(bitmap); 200 paint = refPaint(paint); 201 202 addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint)); 203 return DrawGlInfo::kStatusDone; 204} 205 206status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix, 207 const SkPaint* paint) { 208 bitmap = refBitmap(bitmap); 209 matrix = refMatrix(matrix); 210 paint = refPaint(paint); 211 212 addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint)); 213 return DrawGlInfo::kStatusDone; 214} 215 216status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, 217 float srcRight, float srcBottom, float dstLeft, float dstTop, 218 float dstRight, float dstBottom, const SkPaint* paint) { 219 bitmap = refBitmap(bitmap); 220 paint = refPaint(paint); 221 222 if (srcLeft == 0 && srcTop == 0 && 223 srcRight == bitmap->width() && srcBottom == bitmap->height() && 224 (srcBottom - srcTop == dstBottom - dstTop) && 225 (srcRight - srcLeft == dstRight - dstLeft)) { 226 // transform simple rect to rect drawing case into position bitmap ops, since they merge 227 addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint)); 228 return DrawGlInfo::kStatusDone; 229 } 230 231 addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap, 232 srcLeft, srcTop, srcRight, srcBottom, 233 dstLeft, dstTop, dstRight, dstBottom, paint)); 234 return DrawGlInfo::kStatusDone; 235} 236 237status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top, 238 const SkPaint* paint) { 239 bitmap = refBitmapData(bitmap); 240 paint = refPaint(paint); 241 242 addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint)); 243 return DrawGlInfo::kStatusDone; 244} 245 246status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, 247 const float* vertices, const int* colors, const SkPaint* paint) { 248 int vertexCount = (meshWidth + 1) * (meshHeight + 1); 249 bitmap = refBitmap(bitmap); 250 vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex 251 paint = refPaint(paint); 252 colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex 253 254 addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, 255 vertices, colors, paint)); 256 return DrawGlInfo::kStatusDone; 257} 258 259status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, 260 float left, float top, float right, float bottom, const SkPaint* paint) { 261 bitmap = refBitmap(bitmap); 262 patch = refPatch(patch); 263 paint = refPaint(paint); 264 265 addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint)); 266 return DrawGlInfo::kStatusDone; 267} 268 269status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 270 addDrawOp(new (alloc()) DrawColorOp(color, mode)); 271 return DrawGlInfo::kStatusDone; 272} 273 274status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 275 const SkPaint* paint) { 276 paint = refPaint(paint); 277 addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); 278 return DrawGlInfo::kStatusDone; 279} 280 281status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, 282 float rx, float ry, const SkPaint* paint) { 283 paint = refPaint(paint); 284 addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); 285 return DrawGlInfo::kStatusDone; 286} 287 288status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { 289 paint = refPaint(paint); 290 addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); 291 return DrawGlInfo::kStatusDone; 292} 293 294status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, 295 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { 296 mDisplayListData->refProperty(x); 297 mDisplayListData->refProperty(y); 298 mDisplayListData->refProperty(radius); 299 mDisplayListData->refProperty(paint); 300 addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value, 301 &radius->value, &paint->value)); 302 return DrawGlInfo::kStatusDone; 303} 304 305status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, 306 const SkPaint* paint) { 307 paint = refPaint(paint); 308 addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); 309 return DrawGlInfo::kStatusDone; 310} 311 312status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, 313 float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { 314 paint = refPaint(paint); 315 addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, 316 startAngle, sweepAngle, useCenter, paint)); 317 return DrawGlInfo::kStatusDone; 318} 319 320status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) { 321 path = refPath(path); 322 paint = refPaint(paint); 323 324 addDrawOp(new (alloc()) DrawPathOp(path, paint)); 325 return DrawGlInfo::kStatusDone; 326} 327 328status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) { 329 points = refBuffer<float>(points, count); 330 paint = refPaint(paint); 331 332 addDrawOp(new (alloc()) DrawLinesOp(points, count, paint)); 333 return DrawGlInfo::kStatusDone; 334} 335 336status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) { 337 points = refBuffer<float>(points, count); 338 paint = refPaint(paint); 339 340 addDrawOp(new (alloc()) DrawPointsOp(points, count, paint)); 341 return DrawGlInfo::kStatusDone; 342} 343 344status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, 345 const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) { 346 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 347 348 text = refText(text, bytesCount); 349 path = refPath(path); 350 paint = refPaint(paint); 351 352 DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, 353 hOffset, vOffset, paint); 354 addDrawOp(op); 355 return DrawGlInfo::kStatusDone; 356} 357 358status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, 359 const float* positions, const SkPaint* paint) { 360 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 361 362 text = refText(text, bytesCount); 363 positions = refBuffer<float>(positions, count * 2); 364 paint = refPaint(paint); 365 366 DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); 367 addDrawOp(op); 368 return DrawGlInfo::kStatusDone; 369} 370 371status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 372 float x, float y, const float* positions, const SkPaint* paint, 373 float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) { 374 375 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 376 377 text = refText(text, bytesCount); 378 positions = refBuffer<float>(positions, count * 2); 379 paint = refPaint(paint); 380 381 DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, 382 x, y, positions, paint, totalAdvance, bounds); 383 addDrawOp(op); 384 return DrawGlInfo::kStatusDone; 385} 386 387status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) { 388 if (count <= 0) return DrawGlInfo::kStatusDone; 389 390 rects = refBuffer<float>(rects, count); 391 paint = refPaint(paint); 392 addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); 393 return DrawGlInfo::kStatusDone; 394} 395 396void DisplayListRenderer::resetPaintFilter() { 397 addStateOp(new (alloc()) ResetPaintFilterOp()); 398} 399 400void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { 401 addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); 402} 403 404void DisplayListRenderer::insertRestoreToCount() { 405 if (mRestoreSaveCount >= 0) { 406 DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount); 407 mDisplayListData->displayListOps.add(op); 408 mRestoreSaveCount = -1; 409 } 410} 411 412void DisplayListRenderer::insertTranslate() { 413 if (mHasTranslate) { 414 if (mTranslateX != 0.0f || mTranslateY != 0.0f) { 415 DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY); 416 mDisplayListData->displayListOps.add(op); 417 mTranslateX = mTranslateY = 0.0f; 418 } 419 mHasTranslate = false; 420 } 421} 422 423void DisplayListRenderer::addStateOp(StateOp* op) { 424 addOpInternal(op); 425} 426 427void DisplayListRenderer::addDrawOp(DrawOp* op) { 428 Rect localBounds; 429 if (op->getLocalBounds(mDrawModifiers, localBounds)) { 430 bool rejected = quickRejectConservative(localBounds.left, localBounds.top, 431 localBounds.right, localBounds.bottom); 432 op->setQuickRejected(rejected); 433 } 434 435 mDisplayListData->hasDrawOps = true; 436 addOpInternal(op); 437} 438 439}; // namespace uirenderer 440}; // namespace android 441