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