DisplayListRenderer.cpp revision 44fd8d24f761f82d21e9b00932648a1b6bf91449
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 "DisplayList.h" 25#include "DeferredDisplayList.h" 26#include "DisplayListLogBuffer.h" 27#include "DisplayListOp.h" 28#include "DisplayListRenderer.h" 29#include "Caches.h" 30 31namespace android { 32namespace uirenderer { 33 34DisplayListRenderer::DisplayListRenderer(): 35 mCaches(Caches::getInstance()), 36 mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), 37 mRestoreSaveCount(-1), mDisplayListData(0) { 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 mShaderMap.clear(); 51 mPaintMap.clear(); 52 mRegionMap.clear(); 53 mPathMap.clear(); 54 DisplayListData* data = mDisplayListData; 55 mDisplayListData = 0; 56 return data; 57} 58 59void DisplayListRenderer::setViewport(int width, int height) { 60 // TODO: DisplayListRenderer shouldn't have a projection matrix, as it should never be used 61 mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1); 62 63 initializeViewport(width, height); 64} 65 66status_t DisplayListRenderer::prepareDirty(float left, float top, 67 float right, float bottom, bool opaque) { 68 69 LOG_ALWAYS_FATAL_IF(mDisplayListData, 70 "prepareDirty called a second time during a recording!"); 71 mDisplayListData = new DisplayListData(); 72 73 initializeSaveStack(0, 0, getWidth(), getHeight()); 74 75 mDirtyClip = opaque; 76 mRestoreSaveCount = -1; 77 78 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 79} 80 81void DisplayListRenderer::finish() { 82 insertRestoreToCount(); 83 insertTranslate(); 84} 85 86void DisplayListRenderer::interrupt() { 87} 88 89void DisplayListRenderer::resume() { 90} 91 92status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { 93 // Ignore dirty during recording, it matters only when we replay 94 addDrawOp(new (alloc()) DrawFunctorOp(functor)); 95 mDisplayListData->functorCount++; 96 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 97} 98 99int DisplayListRenderer::save(int flags) { 100 addStateOp(new (alloc()) SaveOp(flags)); 101 return StatefulBaseRenderer::save(flags); 102} 103 104void DisplayListRenderer::restore() { 105 if (mRestoreSaveCount < 0) { 106 restoreToCount(getSaveCount() - 1); 107 return; 108 } 109 110 mRestoreSaveCount--; 111 insertTranslate(); 112 StatefulBaseRenderer::restore(); 113} 114 115void DisplayListRenderer::restoreToCount(int saveCount) { 116 mRestoreSaveCount = saveCount; 117 insertTranslate(); 118 StatefulBaseRenderer::restoreToCount(saveCount); 119} 120 121int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 122 const SkPaint* paint, int flags) { 123 paint = refPaint(paint); 124 addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags)); 125 return StatefulBaseRenderer::save(flags); 126} 127 128void DisplayListRenderer::translate(float dx, float dy, float dz) { 129 // ignore dz, not used at defer time 130 mHasTranslate = true; 131 mTranslateX += dx; 132 mTranslateY += dy; 133 insertRestoreToCount(); 134 StatefulBaseRenderer::translate(dx, dy, dz); 135} 136 137void DisplayListRenderer::rotate(float degrees) { 138 addStateOp(new (alloc()) RotateOp(degrees)); 139 StatefulBaseRenderer::rotate(degrees); 140} 141 142void DisplayListRenderer::scale(float sx, float sy) { 143 addStateOp(new (alloc()) ScaleOp(sx, sy)); 144 StatefulBaseRenderer::scale(sx, sy); 145} 146 147void DisplayListRenderer::skew(float sx, float sy) { 148 addStateOp(new (alloc()) SkewOp(sx, sy)); 149 StatefulBaseRenderer::skew(sx, sy); 150} 151 152void DisplayListRenderer::setMatrix(const SkMatrix* matrix) { 153 matrix = refMatrix(matrix); 154 addStateOp(new (alloc()) SetMatrixOp(matrix)); 155 StatefulBaseRenderer::setMatrix(matrix); 156} 157 158void DisplayListRenderer::concatMatrix(const SkMatrix* matrix) { 159 matrix = refMatrix(matrix); 160 addStateOp(new (alloc()) ConcatMatrixOp(matrix)); 161 StatefulBaseRenderer::concatMatrix(matrix); 162} 163 164bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 165 SkRegion::Op op) { 166 addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); 167 return StatefulBaseRenderer::clipRect(left, top, right, bottom, op); 168} 169 170bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) { 171 path = refPath(path); 172 addStateOp(new (alloc()) ClipPathOp(path, op)); 173 return StatefulBaseRenderer::clipPath(path, op); 174} 175 176bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { 177 region = refRegion(region); 178 addStateOp(new (alloc()) ClipRegionOp(region, op)); 179 return StatefulBaseRenderer::clipRegion(region, op); 180} 181 182status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, 183 Rect& dirty, int32_t flags) { 184 // dirty is an out parameter and should not be recorded, 185 // it matters only when replaying the display list 186 187 // TODO: To be safe, the display list should be ref-counted in the 188 // resources cache, but we rely on the caller (UI toolkit) to 189 // do the right thing for now 190 191 DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList, 192 flags, *currentTransform()); 193 addDrawOp(op); 194 mDisplayListData->children.push(op); 195 if (displayList->isProjectionReceiver()) { 196 mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1; 197 } 198 199 return DrawGlInfo::kStatusDone; 200} 201 202status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) { 203 layer = refLayer(layer); 204 addDrawOp(new (alloc()) DrawLayerOp(layer, x, y)); 205 return DrawGlInfo::kStatusDone; 206} 207 208status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top, 209 const SkPaint* paint) { 210 bitmap = refBitmap(bitmap); 211 paint = refPaint(paint); 212 213 addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint)); 214 return DrawGlInfo::kStatusDone; 215} 216 217status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix, 218 const SkPaint* paint) { 219 bitmap = refBitmap(bitmap); 220 matrix = refMatrix(matrix); 221 paint = refPaint(paint); 222 223 addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint)); 224 return DrawGlInfo::kStatusDone; 225} 226 227status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop, 228 float srcRight, float srcBottom, float dstLeft, float dstTop, 229 float dstRight, float dstBottom, const SkPaint* paint) { 230 bitmap = refBitmap(bitmap); 231 paint = refPaint(paint); 232 233 if (srcLeft == 0 && srcTop == 0 && 234 srcRight == bitmap->width() && srcBottom == bitmap->height() && 235 (srcBottom - srcTop == dstBottom - dstTop) && 236 (srcRight - srcLeft == dstRight - dstLeft)) { 237 // transform simple rect to rect drawing case into position bitmap ops, since they merge 238 addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint)); 239 return DrawGlInfo::kStatusDone; 240 } 241 242 addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap, 243 srcLeft, srcTop, srcRight, srcBottom, 244 dstLeft, dstTop, dstRight, dstBottom, paint)); 245 return DrawGlInfo::kStatusDone; 246} 247 248status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top, 249 const SkPaint* paint) { 250 bitmap = refBitmapData(bitmap); 251 paint = refPaint(paint); 252 253 addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint)); 254 return DrawGlInfo::kStatusDone; 255} 256 257status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight, 258 const float* vertices, const int* colors, const SkPaint* paint) { 259 int count = (meshWidth + 1) * (meshHeight + 1) * 2; 260 bitmap = refBitmap(bitmap); 261 vertices = refBuffer<float>(vertices, count); 262 paint = refPaint(paint); 263 colors = refBuffer<int>(colors, count); 264 265 addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, 266 vertices, colors, paint)); 267 return DrawGlInfo::kStatusDone; 268} 269 270status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch, 271 float left, float top, float right, float bottom, const SkPaint* paint) { 272 bitmap = refBitmap(bitmap); 273 patch = refPatch(patch); 274 paint = refPaint(paint); 275 276 addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint)); 277 return DrawGlInfo::kStatusDone; 278} 279 280status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 281 addDrawOp(new (alloc()) DrawColorOp(color, mode)); 282 return DrawGlInfo::kStatusDone; 283} 284 285status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 286 const SkPaint* paint) { 287 paint = refPaint(paint); 288 addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); 289 return DrawGlInfo::kStatusDone; 290} 291 292status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, 293 float rx, float ry, const SkPaint* paint) { 294 paint = refPaint(paint); 295 addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); 296 return DrawGlInfo::kStatusDone; 297} 298 299status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) { 300 paint = refPaint(paint); 301 addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); 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::resetShader() { 397 addStateOp(new (alloc()) ResetShaderOp()); 398} 399 400void DisplayListRenderer::setupShader(SkiaShader* shader) { 401 shader = refShader(shader); 402 addStateOp(new (alloc()) SetupShaderOp(shader)); 403} 404 405void DisplayListRenderer::resetShadow() { 406 addStateOp(new (alloc()) ResetShadowOp()); 407 OpenGLRenderer::resetShadow(); 408} 409 410void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 411 addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color)); 412 OpenGLRenderer::setupShadow(radius, dx, dy, color); 413} 414 415void DisplayListRenderer::resetPaintFilter() { 416 addStateOp(new (alloc()) ResetPaintFilterOp()); 417} 418 419void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { 420 addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); 421} 422 423void DisplayListRenderer::insertRestoreToCount() { 424 if (mRestoreSaveCount >= 0) { 425 DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount); 426 mDisplayListData->displayListOps.add(op); 427 mRestoreSaveCount = -1; 428 } 429} 430 431void DisplayListRenderer::insertTranslate() { 432 if (mHasTranslate) { 433 if (mTranslateX != 0.0f || mTranslateY != 0.0f) { 434 DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY); 435 mDisplayListData->displayListOps.add(op); 436 mTranslateX = mTranslateY = 0.0f; 437 } 438 mHasTranslate = false; 439 } 440} 441 442void DisplayListRenderer::addStateOp(StateOp* op) { 443 addOpInternal(op); 444} 445 446void DisplayListRenderer::addDrawOp(DrawOp* op) { 447 Rect localBounds; 448 if (op->getLocalBounds(mDrawModifiers, localBounds)) { 449 bool rejected = quickRejectConservative(localBounds.left, localBounds.top, 450 localBounds.right, localBounds.bottom); 451 op->setQuickRejected(rejected); 452 } 453 454 mDisplayListData->hasDrawOps = true; 455 addOpInternal(op); 456} 457 458}; // namespace uirenderer 459}; // namespace android 460