| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 visitor->trace(m_inspectedFrames); | 175 visitor->trace(m_inspectedFrames); |
| 176 InspectorBaseAgent::trace(visitor); | 176 InspectorBaseAgent::trace(visitor); |
| 177 } | 177 } |
| 178 | 178 |
| 179 void InspectorLayerTreeAgent::restore() { | 179 void InspectorLayerTreeAgent::restore() { |
| 180 // We do not re-enable layer agent automatically after navigation. This is | 180 // We do not re-enable layer agent automatically after navigation. This is |
| 181 // because it depends on DOMAgent and node ids in particular, so we let | 181 // because it depends on DOMAgent and node ids in particular, so we let |
| 182 // front-end request document and re-enable the agent manually after this. | 182 // front-end request document and re-enable the agent manually after this. |
| 183 } | 183 } |
| 184 | 184 |
| 185 void InspectorLayerTreeAgent::enable(ErrorString*) { | 185 Response InspectorLayerTreeAgent::enable() { |
| 186 m_instrumentingAgents->addInspectorLayerTreeAgent(this); | 186 m_instrumentingAgents->addInspectorLayerTreeAgent(this); |
| 187 Document* document = m_inspectedFrames->root()->document(); | 187 Document* document = m_inspectedFrames->root()->document(); |
| 188 if (document && | 188 if (document && |
| 189 document->lifecycle().state() >= DocumentLifecycle::CompositingClean) | 189 document->lifecycle().state() >= DocumentLifecycle::CompositingClean) |
| 190 layerTreeDidChange(); | 190 layerTreeDidChange(); |
| 191 return Response::OK(); |
| 191 } | 192 } |
| 192 | 193 |
| 193 void InspectorLayerTreeAgent::disable(ErrorString*) { | 194 Response InspectorLayerTreeAgent::disable() { |
| 194 m_instrumentingAgents->removeInspectorLayerTreeAgent(this); | 195 m_instrumentingAgents->removeInspectorLayerTreeAgent(this); |
| 195 m_snapshotById.clear(); | 196 m_snapshotById.clear(); |
| 196 ErrorString unused; | 197 return Response::OK(); |
| 197 } | 198 } |
| 198 | 199 |
| 199 void InspectorLayerTreeAgent::layerTreeDidChange() { | 200 void InspectorLayerTreeAgent::layerTreeDidChange() { |
| 200 frontend()->layerTreeDidChange(buildLayerTree()); | 201 frontend()->layerTreeDidChange(buildLayerTree()); |
| 201 } | 202 } |
| 202 | 203 |
| 203 void InspectorLayerTreeAgent::didPaint(const GraphicsLayer* graphicsLayer, | 204 void InspectorLayerTreeAgent::didPaint(const GraphicsLayer* graphicsLayer, |
| 204 GraphicsContext&, | 205 GraphicsContext&, |
| 205 const LayoutRect& rect) { | 206 const LayoutRect& rect) { |
| 206 if (m_suppressLayerPaintEvents) | 207 if (m_suppressLayerPaintEvents) |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 static GraphicsLayer* findLayerById(GraphicsLayer* root, int layerId) { | 309 static GraphicsLayer* findLayerById(GraphicsLayer* root, int layerId) { |
| 309 if (root->platformLayer()->id() == layerId) | 310 if (root->platformLayer()->id() == layerId) |
| 310 return root; | 311 return root; |
| 311 for (size_t i = 0, size = root->children().size(); i < size; ++i) { | 312 for (size_t i = 0, size = root->children().size(); i < size; ++i) { |
| 312 if (GraphicsLayer* layer = findLayerById(root->children()[i], layerId)) | 313 if (GraphicsLayer* layer = findLayerById(root->children()[i], layerId)) |
| 313 return layer; | 314 return layer; |
| 314 } | 315 } |
| 315 return nullptr; | 316 return nullptr; |
| 316 } | 317 } |
| 317 | 318 |
| 318 GraphicsLayer* InspectorLayerTreeAgent::layerById(ErrorString* errorString, | 319 Response InspectorLayerTreeAgent::layerById(const String& layerId, |
| 319 const String& layerId) { | 320 GraphicsLayer*& result) { |
| 320 bool ok; | 321 bool ok; |
| 321 int id = layerId.toInt(&ok); | 322 int id = layerId.toInt(&ok); |
| 322 if (!ok) { | 323 if (!ok) |
| 323 *errorString = "Invalid layer id"; | 324 return Response::Error("Invalid layer id"); |
| 324 return nullptr; | |
| 325 } | |
| 326 PaintLayerCompositor* compositor = paintLayerCompositor(); | 325 PaintLayerCompositor* compositor = paintLayerCompositor(); |
| 327 if (!compositor) { | 326 if (!compositor) |
| 328 *errorString = "Not in compositing mode"; | 327 return Response::Error("Not in compositing mode"); |
| 329 return nullptr; | |
| 330 } | |
| 331 | 328 |
| 332 GraphicsLayer* result = findLayerById(rootGraphicsLayer(), id); | 329 result = findLayerById(rootGraphicsLayer(), id); |
| 333 if (!result) | 330 if (!result) |
| 334 *errorString = "No layer matching given id found"; | 331 return Response::Error("No layer matching given id found"); |
| 335 return result; | 332 return Response::OK(); |
| 336 } | 333 } |
| 337 | 334 |
| 338 void InspectorLayerTreeAgent::compositingReasons( | 335 Response InspectorLayerTreeAgent::compositingReasons( |
| 339 ErrorString* errorString, | |
| 340 const String& layerId, | 336 const String& layerId, |
| 341 std::unique_ptr<Array<String>>* reasonStrings) { | 337 std::unique_ptr<Array<String>>* reasonStrings) { |
| 342 const GraphicsLayer* graphicsLayer = layerById(errorString, layerId); | 338 GraphicsLayer* graphicsLayer = nullptr; |
| 343 if (!graphicsLayer) | 339 Response response = layerById(layerId, graphicsLayer); |
| 344 return; | 340 if (!response.isSuccess()) |
| 341 return response; |
| 345 CompositingReasons reasonsBitmask = graphicsLayer->getCompositingReasons(); | 342 CompositingReasons reasonsBitmask = graphicsLayer->getCompositingReasons(); |
| 346 *reasonStrings = Array<String>::create(); | 343 *reasonStrings = Array<String>::create(); |
| 347 for (size_t i = 0; i < kNumberOfCompositingReasons; ++i) { | 344 for (size_t i = 0; i < kNumberOfCompositingReasons; ++i) { |
| 348 if (!(reasonsBitmask & kCompositingReasonStringMap[i].reason)) | 345 if (!(reasonsBitmask & kCompositingReasonStringMap[i].reason)) |
| 349 continue; | 346 continue; |
| 350 (*reasonStrings)->addItem(kCompositingReasonStringMap[i].shortName); | 347 (*reasonStrings)->addItem(kCompositingReasonStringMap[i].shortName); |
| 351 #ifndef _NDEBUG | 348 #ifndef _NDEBUG |
| 352 reasonsBitmask &= ~kCompositingReasonStringMap[i].reason; | 349 reasonsBitmask &= ~kCompositingReasonStringMap[i].reason; |
| 353 #endif | 350 #endif |
| 354 } | 351 } |
| 355 ASSERT(!reasonsBitmask); | 352 ASSERT(!reasonsBitmask); |
| 353 return Response::OK(); |
| 356 } | 354 } |
| 357 | 355 |
| 358 void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, | 356 Response InspectorLayerTreeAgent::makeSnapshot(const String& layerId, |
| 359 const String& layerId, | 357 String* snapshotId) { |
| 360 String* snapshotId) { | 358 GraphicsLayer* layer = nullptr; |
| 361 GraphicsLayer* layer = layerById(errorString, layerId); | 359 Response response = layerById(layerId, layer); |
| 362 if (!layer || !layer->drawsContent()) | 360 if (!response.isSuccess()) |
| 363 return; | 361 return response; |
| 362 if (!layer->drawsContent()) |
| 363 return Response::Error("Layer does not draw content"); |
| 364 | 364 |
| 365 IntSize size = expandedIntSize(layer->size()); | 365 IntSize size = expandedIntSize(layer->size()); |
| 366 | 366 |
| 367 IntRect interestRect(IntPoint(0, 0), size); | 367 IntRect interestRect(IntPoint(0, 0), size); |
| 368 m_suppressLayerPaintEvents = true; | 368 m_suppressLayerPaintEvents = true; |
| 369 layer->paint(&interestRect); | 369 layer->paint(&interestRect); |
| 370 m_suppressLayerPaintEvents = false; | 370 m_suppressLayerPaintEvents = false; |
| 371 | 371 |
| 372 GraphicsContext context(layer->getPaintController()); | 372 GraphicsContext context(layer->getPaintController()); |
| 373 context.beginRecording(interestRect); | 373 context.beginRecording(interestRect); |
| 374 layer->getPaintController().paintArtifact().replay(context); | 374 layer->getPaintController().paintArtifact().replay(context); |
| 375 RefPtr<PictureSnapshot> snapshot = | 375 RefPtr<PictureSnapshot> snapshot = |
| 376 adoptRef(new PictureSnapshot(context.endRecording())); | 376 adoptRef(new PictureSnapshot(context.endRecording())); |
| 377 | 377 |
| 378 *snapshotId = String::number(++s_lastSnapshotId); | 378 *snapshotId = String::number(++s_lastSnapshotId); |
| 379 bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry; | 379 bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry; |
| 380 DCHECK(newEntry); | 380 DCHECK(newEntry); |
| 381 return Response::OK(); |
| 381 } | 382 } |
| 382 | 383 |
| 383 void InspectorLayerTreeAgent::loadSnapshot( | 384 Response InspectorLayerTreeAgent::loadSnapshot( |
| 384 ErrorString* errorString, | |
| 385 std::unique_ptr<Array<protocol::LayerTree::PictureTile>> tiles, | 385 std::unique_ptr<Array<protocol::LayerTree::PictureTile>> tiles, |
| 386 String* snapshotId) { | 386 String* snapshotId) { |
| 387 if (!tiles->length()) { | 387 if (!tiles->length()) |
| 388 *errorString = "Invalid argument, no tiles provided"; | 388 return Response::Error("Invalid argument, no tiles provided"); |
| 389 return; | |
| 390 } | |
| 391 Vector<RefPtr<PictureSnapshot::TilePictureStream>> decodedTiles; | 389 Vector<RefPtr<PictureSnapshot::TilePictureStream>> decodedTiles; |
| 392 decodedTiles.grow(tiles->length()); | 390 decodedTiles.grow(tiles->length()); |
| 393 for (size_t i = 0; i < tiles->length(); ++i) { | 391 for (size_t i = 0; i < tiles->length(); ++i) { |
| 394 protocol::LayerTree::PictureTile* tile = tiles->get(i); | 392 protocol::LayerTree::PictureTile* tile = tiles->get(i); |
| 395 decodedTiles[i] = adoptRef(new PictureSnapshot::TilePictureStream()); | 393 decodedTiles[i] = adoptRef(new PictureSnapshot::TilePictureStream()); |
| 396 decodedTiles[i]->layerOffset.set(tile->getX(), tile->getY()); | 394 decodedTiles[i]->layerOffset.set(tile->getX(), tile->getY()); |
| 397 if (!base64Decode(tile->getPicture(), decodedTiles[i]->data)) { | 395 if (!base64Decode(tile->getPicture(), decodedTiles[i]->data)) |
| 398 *errorString = "Invalid base64 encoding"; | 396 return Response::Error("Invalid base64 encoding"); |
| 399 return; | |
| 400 } | |
| 401 } | 397 } |
| 402 RefPtr<PictureSnapshot> snapshot = PictureSnapshot::load(decodedTiles); | 398 RefPtr<PictureSnapshot> snapshot = PictureSnapshot::load(decodedTiles); |
| 403 if (!snapshot) { | 399 if (!snapshot) |
| 404 *errorString = "Invalid snapshot format"; | 400 return Response::Error("Invalid snapshot format"); |
| 405 return; | 401 if (snapshot->isEmpty()) |
| 406 } | 402 return Response::Error("Empty snapshot"); |
| 407 if (snapshot->isEmpty()) { | |
| 408 *errorString = "Empty snapshot"; | |
| 409 return; | |
| 410 } | |
| 411 | 403 |
| 412 *snapshotId = String::number(++s_lastSnapshotId); | 404 *snapshotId = String::number(++s_lastSnapshotId); |
| 413 bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry; | 405 bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry; |
| 414 DCHECK(newEntry); | 406 DCHECK(newEntry); |
| 407 return Response::OK(); |
| 415 } | 408 } |
| 416 | 409 |
| 417 void InspectorLayerTreeAgent::releaseSnapshot(ErrorString* errorString, | 410 Response InspectorLayerTreeAgent::releaseSnapshot(const String& snapshotId) { |
| 418 const String& snapshotId) { | |
| 419 SnapshotById::iterator it = m_snapshotById.find(snapshotId); | 411 SnapshotById::iterator it = m_snapshotById.find(snapshotId); |
| 420 if (it == m_snapshotById.end()) { | 412 if (it == m_snapshotById.end()) |
| 421 *errorString = "Snapshot not found"; | 413 return Response::Error("Snapshot not found"); |
| 422 return; | |
| 423 } | |
| 424 m_snapshotById.remove(it); | 414 m_snapshotById.remove(it); |
| 415 return Response::OK(); |
| 425 } | 416 } |
| 426 | 417 |
| 427 const PictureSnapshot* InspectorLayerTreeAgent::snapshotById( | 418 Response InspectorLayerTreeAgent::snapshotById(const String& snapshotId, |
| 428 ErrorString* errorString, | 419 const PictureSnapshot*& result) { |
| 429 const String& snapshotId) { | |
| 430 SnapshotById::iterator it = m_snapshotById.find(snapshotId); | 420 SnapshotById::iterator it = m_snapshotById.find(snapshotId); |
| 431 if (it == m_snapshotById.end()) { | 421 if (it == m_snapshotById.end()) |
| 432 *errorString = "Snapshot not found"; | 422 return Response::Error("Snapshot not found"); |
| 433 return nullptr; | 423 result = it->value.get(); |
| 434 } | 424 return Response::OK(); |
| 435 return it->value.get(); | |
| 436 } | 425 } |
| 437 | 426 |
| 438 void InspectorLayerTreeAgent::replaySnapshot(ErrorString* errorString, | 427 Response InspectorLayerTreeAgent::replaySnapshot(const String& snapshotId, |
| 439 const String& snapshotId, | 428 Maybe<int> fromStep, |
| 440 const Maybe<int>& fromStep, | 429 Maybe<int> toStep, |
| 441 const Maybe<int>& toStep, | 430 Maybe<double> scale, |
| 442 const Maybe<double>& scale, | 431 String* dataURL) { |
| 443 String* dataURL) { | 432 const PictureSnapshot* snapshot = nullptr; |
| 444 const PictureSnapshot* snapshot = snapshotById(errorString, snapshotId); | 433 Response response = snapshotById(snapshotId, snapshot); |
| 445 if (!snapshot) | 434 if (!response.isSuccess()) |
| 446 return; | 435 return response; |
| 447 std::unique_ptr<Vector<char>> base64Data = snapshot->replay( | 436 std::unique_ptr<Vector<char>> base64Data = snapshot->replay( |
| 448 fromStep.fromMaybe(0), toStep.fromMaybe(0), scale.fromMaybe(1.0)); | 437 fromStep.fromMaybe(0), toStep.fromMaybe(0), scale.fromMaybe(1.0)); |
| 449 if (!base64Data) { | 438 if (!base64Data) |
| 450 *errorString = "Image encoding failed"; | 439 return Response::Error("Image encoding failed"); |
| 451 return; | |
| 452 } | |
| 453 StringBuilder url; | 440 StringBuilder url; |
| 454 url.append("data:image/png;base64,"); | 441 url.append("data:image/png;base64,"); |
| 455 url.reserveCapacity(url.length() + base64Data->size()); | 442 url.reserveCapacity(url.length() + base64Data->size()); |
| 456 url.append(base64Data->begin(), base64Data->size()); | 443 url.append(base64Data->begin(), base64Data->size()); |
| 457 *dataURL = url.toString(); | 444 *dataURL = url.toString(); |
| 445 return Response::OK(); |
| 458 } | 446 } |
| 459 | 447 |
| 460 static void parseRect(protocol::DOM::Rect* object, FloatRect* rect) { | 448 static void parseRect(protocol::DOM::Rect* object, FloatRect* rect) { |
| 461 *rect = FloatRect(object->getX(), object->getY(), object->getWidth(), | 449 *rect = FloatRect(object->getX(), object->getY(), object->getWidth(), |
| 462 object->getHeight()); | 450 object->getHeight()); |
| 463 } | 451 } |
| 464 | 452 |
| 465 void InspectorLayerTreeAgent::profileSnapshot( | 453 Response InspectorLayerTreeAgent::profileSnapshot( |
| 466 ErrorString* errorString, | |
| 467 const String& snapshotId, | 454 const String& snapshotId, |
| 468 const protocol::Maybe<int>& minRepeatCount, | 455 Maybe<int> minRepeatCount, |
| 469 const protocol::Maybe<double>& minDuration, | 456 Maybe<double> minDuration, |
| 470 const Maybe<protocol::DOM::Rect>& clipRect, | 457 Maybe<protocol::DOM::Rect> clipRect, |
| 471 std::unique_ptr<protocol::Array<protocol::Array<double>>>* outTimings) { | 458 std::unique_ptr<protocol::Array<protocol::Array<double>>>* outTimings) { |
| 472 const PictureSnapshot* snapshot = snapshotById(errorString, snapshotId); | 459 const PictureSnapshot* snapshot = nullptr; |
| 473 if (!snapshot) | 460 Response response = snapshotById(snapshotId, snapshot); |
| 474 return; | 461 if (!response.isSuccess()) |
| 462 return response; |
| 475 FloatRect rect; | 463 FloatRect rect; |
| 476 if (clipRect.isJust()) | 464 if (clipRect.isJust()) |
| 477 parseRect(clipRect.fromJust(), &rect); | 465 parseRect(clipRect.fromJust(), &rect); |
| 478 std::unique_ptr<PictureSnapshot::Timings> timings = | 466 std::unique_ptr<PictureSnapshot::Timings> timings = |
| 479 snapshot->profile(minRepeatCount.fromMaybe(1), minDuration.fromMaybe(0), | 467 snapshot->profile(minRepeatCount.fromMaybe(1), minDuration.fromMaybe(0), |
| 480 clipRect.isJust() ? &rect : 0); | 468 clipRect.isJust() ? &rect : 0); |
| 481 *outTimings = Array<Array<double>>::create(); | 469 *outTimings = Array<Array<double>>::create(); |
| 482 for (size_t i = 0; i < timings->size(); ++i) { | 470 for (size_t i = 0; i < timings->size(); ++i) { |
| 483 const Vector<double>& row = (*timings)[i]; | 471 const Vector<double>& row = (*timings)[i]; |
| 484 std::unique_ptr<Array<double>> outRow = Array<double>::create(); | 472 std::unique_ptr<Array<double>> outRow = Array<double>::create(); |
| 485 for (size_t j = 0; j < row.size(); ++j) | 473 for (size_t j = 0; j < row.size(); ++j) |
| 486 outRow->addItem(row[j]); | 474 outRow->addItem(row[j]); |
| 487 (*outTimings)->addItem(std::move(outRow)); | 475 (*outTimings)->addItem(std::move(outRow)); |
| 488 } | 476 } |
| 477 return Response::OK(); |
| 489 } | 478 } |
| 490 | 479 |
| 491 void InspectorLayerTreeAgent::snapshotCommandLog( | 480 Response InspectorLayerTreeAgent::snapshotCommandLog( |
| 492 ErrorString* errorString, | |
| 493 const String& snapshotId, | 481 const String& snapshotId, |
| 494 std::unique_ptr<Array<protocol::DictionaryValue>>* commandLog) { | 482 std::unique_ptr<Array<protocol::DictionaryValue>>* commandLog) { |
| 495 const PictureSnapshot* snapshot = snapshotById(errorString, snapshotId); | 483 const PictureSnapshot* snapshot = nullptr; |
| 496 if (!snapshot) | 484 Response response = snapshotById(snapshotId, snapshot); |
| 497 return; | 485 if (!response.isSuccess()) |
| 498 protocol::ErrorSupport errors(errorString); | 486 return response; |
| 487 protocol::ErrorSupport errors; |
| 499 std::unique_ptr<protocol::Value> logValue = | 488 std::unique_ptr<protocol::Value> logValue = |
| 500 protocol::parseJSON(snapshot->snapshotCommandLog()->toJSONString()); | 489 protocol::parseJSON(snapshot->snapshotCommandLog()->toJSONString()); |
| 501 *commandLog = | 490 *commandLog = |
| 502 Array<protocol::DictionaryValue>::parse(logValue.get(), &errors); | 491 Array<protocol::DictionaryValue>::parse(logValue.get(), &errors); |
| 492 if (errors.hasErrors()) |
| 493 return Response::Error(errors.errors()); |
| 494 return Response::OK(); |
| 503 } | 495 } |
| 504 | 496 |
| 505 void InspectorLayerTreeAgent::willAddPageOverlay(const GraphicsLayer* layer) { | 497 void InspectorLayerTreeAgent::willAddPageOverlay(const GraphicsLayer* layer) { |
| 506 m_pageOverlayLayerIds.append(layer->platformLayer()->id()); | 498 m_pageOverlayLayerIds.append(layer->platformLayer()->id()); |
| 507 } | 499 } |
| 508 | 500 |
| 509 void InspectorLayerTreeAgent::didRemovePageOverlay(const GraphicsLayer* layer) { | 501 void InspectorLayerTreeAgent::didRemovePageOverlay(const GraphicsLayer* layer) { |
| 510 size_t index = m_pageOverlayLayerIds.find(layer->platformLayer()->id()); | 502 size_t index = m_pageOverlayLayerIds.find(layer->platformLayer()->id()); |
| 511 if (index == WTF::kNotFound) | 503 if (index == WTF::kNotFound) |
| 512 return; | 504 return; |
| 513 m_pageOverlayLayerIds.remove(index); | 505 m_pageOverlayLayerIds.remove(index); |
| 514 } | 506 } |
| 515 | 507 |
| 516 } // namespace blink | 508 } // namespace blink |
| OLD | NEW |