Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/inspector/TimelineTraceEventProcessor.h" | 32 #include "core/inspector/TimelineTraceEventProcessor.h" |
| 33 | 33 |
| 34 #include "core/fetch/ImageResource.h" | 34 #include "core/fetch/ImageResource.h" |
| 35 #include "core/inspector/InspectorClient.h" | 35 #include "core/inspector/InspectorClient.h" |
| 36 #include "core/inspector/InspectorInstrumentation.h" | 36 #include "core/inspector/InspectorInstrumentation.h" |
| 37 #include "core/inspector/TimelineRecordFactory.h" | 37 #include "core/inspector/TimelineRecordFactory.h" |
| 38 #include "core/rendering/RenderImage.h" | 38 #include "core/rendering/RenderImage.h" |
| 39 | 39 |
| 40 #include "wtf/CurrentTime.h" | 40 #include "wtf/CurrentTime.h" |
| 41 #include "wtf/Functional.h" | |
| 41 #include "wtf/MainThread.h" | 42 #include "wtf/MainThread.h" |
| 42 #include "wtf/Vector.h" | 43 #include "wtf/Vector.h" |
| 43 | 44 |
| 44 namespace WebCore { | 45 namespace WebCore { |
| 45 | 46 |
| 46 namespace { | 47 namespace { |
| 47 | 48 |
| 48 class TraceEventDispatcher { | 49 class TraceEventDispatcher { |
| 49 WTF_MAKE_NONCOPYABLE(TraceEventDispatcher); | 50 WTF_MAKE_NONCOPYABLE(TraceEventDispatcher); |
| 50 public: | 51 public: |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 | 150 |
| 150 TimelineTraceEventProcessor::TimelineTraceEventProcessor(WeakPtr<InspectorTimeli neAgent> timelineAgent, InspectorClient *client) | 151 TimelineTraceEventProcessor::TimelineTraceEventProcessor(WeakPtr<InspectorTimeli neAgent> timelineAgent, InspectorClient *client) |
| 151 : m_timelineAgent(timelineAgent) | 152 : m_timelineAgent(timelineAgent) |
| 152 , m_timeConverter(timelineAgent.get()->timeConverter()) | 153 , m_timeConverter(timelineAgent.get()->timeConverter()) |
| 153 , m_inspectorClient(client) | 154 , m_inspectorClient(client) |
| 154 , m_pageId(reinterpret_cast<unsigned long long>(m_timelineAgent.get()->page( ))) | 155 , m_pageId(reinterpret_cast<unsigned long long>(m_timelineAgent.get()->page( ))) |
| 155 , m_layerTreeId(m_timelineAgent.get()->layerTreeId()) | 156 , m_layerTreeId(m_timelineAgent.get()->layerTreeId()) |
| 156 , m_layerId(0) | 157 , m_layerId(0) |
| 157 , m_paintSetupStart(0) | 158 , m_paintSetupStart(0) |
| 158 , m_paintSetupEnd(0) | 159 , m_paintSetupEnd(0) |
| 160 , m_lastEventProcessingTime(0) | |
| 161 , m_processEventsTaskPosted(false) | |
| 159 { | 162 { |
| 160 registerHandler(InstrumentationEvents::BeginFrame, TRACE_EVENT_PHASE_INSTANT , &TimelineTraceEventProcessor::onBeginFrame); | 163 registerHandler(InstrumentationEvents::BeginFrame, TRACE_EVENT_PHASE_INSTANT , &TimelineTraceEventProcessor::onBeginFrame); |
| 161 registerHandler(InstrumentationEvents::UpdateLayer, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onUpdateLayerBegin); | 164 registerHandler(InstrumentationEvents::UpdateLayer, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onUpdateLayerBegin); |
| 162 registerHandler(InstrumentationEvents::UpdateLayer, TRACE_EVENT_PHASE_END, & TimelineTraceEventProcessor::onUpdateLayerEnd); | 165 registerHandler(InstrumentationEvents::UpdateLayer, TRACE_EVENT_PHASE_END, & TimelineTraceEventProcessor::onUpdateLayerEnd); |
| 163 registerHandler(InstrumentationEvents::PaintLayer, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onPaintLayerBegin); | 166 registerHandler(InstrumentationEvents::PaintLayer, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onPaintLayerBegin); |
| 164 registerHandler(InstrumentationEvents::PaintLayer, TRACE_EVENT_PHASE_END, &T imelineTraceEventProcessor::onPaintLayerEnd); | 167 registerHandler(InstrumentationEvents::PaintLayer, TRACE_EVENT_PHASE_END, &T imelineTraceEventProcessor::onPaintLayerEnd); |
| 165 registerHandler(InstrumentationEvents::PaintSetup, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onPaintSetupBegin); | 168 registerHandler(InstrumentationEvents::PaintSetup, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onPaintSetupBegin); |
| 166 registerHandler(InstrumentationEvents::PaintSetup, TRACE_EVENT_PHASE_END, &T imelineTraceEventProcessor::onPaintSetupEnd); | 169 registerHandler(InstrumentationEvents::PaintSetup, TRACE_EVENT_PHASE_END, &T imelineTraceEventProcessor::onPaintSetupEnd); |
| 167 registerHandler(InstrumentationEvents::RasterTask, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onRasterTaskBegin); | 170 registerHandler(InstrumentationEvents::RasterTask, TRACE_EVENT_PHASE_BEGIN, &TimelineTraceEventProcessor::onRasterTaskBegin); |
| 168 registerHandler(InstrumentationEvents::RasterTask, TRACE_EVENT_PHASE_END, &T imelineTraceEventProcessor::onRasterTaskEnd); | 171 registerHandler(InstrumentationEvents::RasterTask, TRACE_EVENT_PHASE_END, &T imelineTraceEventProcessor::onRasterTaskEnd); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 } | 216 } |
| 214 | 217 |
| 215 void TimelineTraceEventProcessor::processEventOnAnyThread(char phase, const char * name, unsigned long long id, | 218 void TimelineTraceEventProcessor::processEventOnAnyThread(char phase, const char * name, unsigned long long id, |
| 216 int numArgs, const char* const* argNames, const unsigned char* argTypes, con st unsigned long long* argValues, | 219 int numArgs, const char* const* argNames, const unsigned char* argTypes, con st unsigned long long* argValues, |
| 217 unsigned char) | 220 unsigned char) |
| 218 { | 221 { |
| 219 HandlersMap::iterator it = m_handlersByType.find(std::make_pair(name, phase) ); | 222 HandlersMap::iterator it = m_handlersByType.find(std::make_pair(name, phase) ); |
| 220 if (it == m_handlersByType.end()) | 223 if (it == m_handlersByType.end()) |
| 221 return; | 224 return; |
| 222 | 225 |
| 223 TraceEvent event(WTF::monotonicallyIncreasingTime(), phase, name, id, curren tThread(), numArgs, argNames, argTypes, argValues); | 226 double timestamp = WTF::monotonicallyIncreasingTime(); |
| 227 TraceEvent event(timestamp, phase, name, id, currentThread(), numArgs, argNa mes, argTypes, argValues); | |
| 224 | 228 |
| 225 if (!isMainThread()) { | 229 if (!isMainThread()) { |
| 226 MutexLocker locker(m_backgroundEventsMutex); | 230 MutexLocker locker(m_backgroundEventsMutex); |
| 231 const float EventProcessingThresholdInSeconds = 0.1; | |
| 227 m_backgroundEvents.append(event); | 232 m_backgroundEvents.append(event); |
| 233 if (!m_processEventsTaskPosted && timestamp - m_lastEventProcessingTime > EventProcessingThresholdInSeconds) { | |
| 234 m_processEventsTaskPosted = true; | |
| 235 callOnMainThread(bind(&TimelineTraceEventProcessor::processBackgroun dEventsTask, this)); | |
| 236 } | |
| 228 return; | 237 return; |
| 229 } | 238 } |
| 239 processBackgroundEvents(); | |
| 230 (this->*(it->value))(event); | 240 (this->*(it->value))(event); |
| 231 } | 241 } |
| 232 | 242 |
| 233 void TimelineTraceEventProcessor::onBeginFrame(const TraceEvent&) | 243 void TimelineTraceEventProcessor::onBeginFrame(const TraceEvent&) |
| 234 { | 244 { |
| 235 processBackgroundEvents(); | 245 // We don't handle BeginFrame explicitly now, but it still implicitly helps |
| 246 // to pump the background events regularly (as opponsed to a special task), | |
| 247 // as this is only done upon events we recognize. | |
| 236 } | 248 } |
| 237 | 249 |
| 238 void TimelineTraceEventProcessor::onUpdateLayerBegin(const TraceEvent& event) | 250 void TimelineTraceEventProcessor::onUpdateLayerBegin(const TraceEvent& event) |
| 239 { | 251 { |
| 240 unsigned long long layerTreeId = event.asUInt(InstrumentationEventArguments: :LayerTreeId); | 252 unsigned long long layerTreeId = event.asUInt(InstrumentationEventArguments: :LayerTreeId); |
| 241 if (layerTreeId != m_layerTreeId) | 253 if (layerTreeId != m_layerTreeId) |
| 242 return; | 254 return; |
| 243 m_layerId = event.asUInt(InstrumentationEventArguments::LayerId); | 255 m_layerId = event.asUInt(InstrumentationEventArguments::LayerId); |
| 244 // We don't know the node yet. For content layers, the node will be updated | 256 // We don't know the node yet. For content layers, the node will be updated |
| 245 // by paint. For others, let it remain 0 -- we just need the fact that | 257 // by paint. For others, let it remain 0 -- we just need the fact that |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 276 m_paintSetupEnd = m_timeConverter.fromMonotonicallyIncreasingTime(event.time stamp()); | 288 m_paintSetupEnd = m_timeConverter.fromMonotonicallyIncreasingTime(event.time stamp()); |
| 277 } | 289 } |
| 278 | 290 |
| 279 void TimelineTraceEventProcessor::onRasterTaskBegin(const TraceEvent& event) | 291 void TimelineTraceEventProcessor::onRasterTaskBegin(const TraceEvent& event) |
| 280 { | 292 { |
| 281 TimelineThreadState& state = threadState(event.threadIdentifier()); | 293 TimelineThreadState& state = threadState(event.threadIdentifier()); |
| 282 if (!maybeEnterLayerTask(event, state)) | 294 if (!maybeEnterLayerTask(event, state)) |
| 283 return; | 295 return; |
| 284 unsigned long long layerId = event.asUInt(InstrumentationEventArguments::Lay erId); | 296 unsigned long long layerId = event.asUInt(InstrumentationEventArguments::Lay erId); |
| 285 ASSERT(layerId); | 297 ASSERT(layerId); |
| 286 RefPtr<JSONObject> record = createRecord(event, TimelineRecordType::Rasteriz e); | 298 RefPtr<JSONObject> record = createRecord(event, TimelineRecordType::Rasteriz e, TimelineRecordFactory::createLayerData(m_layerToNodeMap.get(layerId))); |
| 287 record->setObject("data", TimelineRecordFactory::createLayerData(m_layerToNo deMap.get(layerId))); | |
| 288 state.recordStack.addScopedRecord(record.release()); | 299 state.recordStack.addScopedRecord(record.release()); |
| 289 } | 300 } |
| 290 | 301 |
| 291 void TimelineTraceEventProcessor::onRasterTaskEnd(const TraceEvent& event) | 302 void TimelineTraceEventProcessor::onRasterTaskEnd(const TraceEvent& event) |
| 292 { | 303 { |
| 293 TimelineThreadState& state = threadState(event.threadIdentifier()); | 304 TimelineThreadState& state = threadState(event.threadIdentifier()); |
| 294 if (!state.inKnownLayerTask) | 305 if (!state.inKnownLayerTask) |
| 295 return; | 306 return; |
| 296 ASSERT(state.recordStack.isOpenRecordOfType(TimelineRecordType::Rasterize)); | 307 ASSERT(state.recordStack.isOpenRecordOfType(TimelineRecordType::Rasterize)); |
| 297 state.recordStack.closeScopedRecord(m_timeConverter.fromMonotonicallyIncreas ingTime(event.timestamp())); | 308 state.recordStack.closeScopedRecord(m_timeConverter.fromMonotonicallyIncreas ingTime(event.timestamp())); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 record->setObject("data", data ? data : JSONObject::create()); | 426 record->setObject("data", data ? data : JSONObject::create()); |
| 416 return record.release(); | 427 return record.release(); |
| 417 } | 428 } |
| 418 | 429 |
| 419 void TimelineTraceEventProcessor::processBackgroundEvents() | 430 void TimelineTraceEventProcessor::processBackgroundEvents() |
| 420 { | 431 { |
| 421 ASSERT(isMainThread()); | 432 ASSERT(isMainThread()); |
| 422 Vector<TraceEvent> events; | 433 Vector<TraceEvent> events; |
| 423 { | 434 { |
| 424 MutexLocker locker(m_backgroundEventsMutex); | 435 MutexLocker locker(m_backgroundEventsMutex); |
| 436 m_lastEventProcessingTime = WTF::monotonicallyIncreasingTime(); | |
| 437 if (!m_backgroundEvents.size()) | |
|
alph
2013/10/16 15:22:23
nit: isEmpty()
| |
| 438 return; | |
| 425 events.reserveCapacity(m_backgroundEvents.capacity()); | 439 events.reserveCapacity(m_backgroundEvents.capacity()); |
| 426 m_backgroundEvents.swap(events); | 440 m_backgroundEvents.swap(events); |
| 427 } | 441 } |
| 428 for (size_t i = 0, size = events.size(); i < size; ++i) { | 442 for (size_t i = 0, size = events.size(); i < size; ++i) { |
| 429 const TraceEvent& event = events[i]; | 443 const TraceEvent& event = events[i]; |
| 430 HandlersMap::iterator it = m_handlersByType.find(std::make_pair(event.na me(), event.phase())); | 444 HandlersMap::iterator it = m_handlersByType.find(std::make_pair(event.na me(), event.phase())); |
| 431 ASSERT(it != m_handlersByType.end() && it->value); | 445 ASSERT(it != m_handlersByType.end() && it->value); |
| 432 (this->*(it->value))(event); | 446 (this->*(it->value))(event); |
| 433 } | 447 } |
| 434 } | 448 } |
| 435 | 449 |
| 450 void TimelineTraceEventProcessor::processBackgroundEventsTask() | |
| 451 { | |
| 452 m_processEventsTaskPosted = false; | |
| 453 processBackgroundEvents(); | |
| 454 } | |
| 455 | |
| 436 } // namespace WebCore | 456 } // namespace WebCore |
| 437 | 457 |
| OLD | NEW |