This source file includes following definitions.
- record
- stop
- m_isCertainlyOpaque
- m_canvas
- canvas
- play
- play
- abortDrawing
- play
- abortDrawing
- timingsVector
- replay
- profile
- createImageBuffer
#include "config.h"
#include "platform/graphics/GraphicsContextRecorder.h"
#include "platform/graphics/ImageBuffer.h"
#include "third_party/skia/include/core/SkBitmapDevice.h"
namespace WebCore {
GraphicsContext* GraphicsContextRecorder::record(const IntSize& size, bool isCertainlyOpaque)
{
ASSERT(!m_picture);
ASSERT(!m_context);
m_picture = adoptRef(new SkPicture());
m_isCertainlyOpaque = isCertainlyOpaque;
SkCanvas* canvas = m_picture->beginRecording(size.width(), size.height());
m_context = adoptPtr(new GraphicsContext(canvas));
m_context->setTrackOpaqueRegion(isCertainlyOpaque);
m_context->setCertainlyOpaque(isCertainlyOpaque);
return m_context.get();
}
PassRefPtr<GraphicsContextSnapshot> GraphicsContextRecorder::stop()
{
m_picture->endRecording();
m_context.clear();
return adoptRef(new GraphicsContextSnapshot(m_picture.release(), m_isCertainlyOpaque));
}
GraphicsContextSnapshot::GraphicsContextSnapshot(PassRefPtr<SkPicture> picture, bool isCertainlyOpaque)
: m_picture(picture)
, m_isCertainlyOpaque(isCertainlyOpaque)
{
}
class SnapshotPlayer : public SkDrawPictureCallback {
WTF_MAKE_NONCOPYABLE(SnapshotPlayer);
public:
explicit SnapshotPlayer(PassRefPtr<SkPicture> picture, SkCanvas* canvas)
: m_picture(picture)
, m_canvas(canvas)
{
}
SkCanvas* canvas() { return m_canvas; }
void play()
{
m_picture->draw(m_canvas, this);
}
private:
RefPtr<SkPicture> m_picture;
SkCanvas* m_canvas;
};
class FragmentSnapshotPlayer : public SnapshotPlayer {
public:
FragmentSnapshotPlayer(PassRefPtr<SkPicture> picture, SkCanvas* canvas)
: SnapshotPlayer(picture, canvas)
{
}
void play(unsigned fromStep, unsigned toStep)
{
m_fromStep = fromStep;
m_toStep = toStep;
m_stepCount = 0;
SnapshotPlayer::play();
}
virtual bool abortDrawing() OVERRIDE
{
++m_stepCount;
if (m_stepCount == m_fromStep) {
const SkBitmap& bitmap = canvas()->getDevice()->accessBitmap(true);
bitmap.eraseARGB(0, 0, 0, 0);
}
return m_toStep && m_stepCount > m_toStep;
}
private:
unsigned m_fromStep;
unsigned m_toStep;
unsigned m_stepCount;
};
class ProfilingSnapshotPlayer : public SnapshotPlayer {
public:
ProfilingSnapshotPlayer(PassRefPtr<SkPicture> picture, SkCanvas* canvas)
: SnapshotPlayer(picture, canvas)
{
}
void play(GraphicsContextSnapshot::Timings* timingsVector, unsigned minRepeatCount, double minDuration)
{
m_timingsVector = timingsVector;
m_timingsVector->reserveCapacity(minRepeatCount);
double now = WTF::monotonicallyIncreasingTime();
double stopTime = now + minDuration;
for (unsigned step = 0; step < minRepeatCount || now < stopTime; ++step) {
m_timingsVector->append(Vector<double>());
m_currentTimings = &m_timingsVector->last();
if (m_timingsVector->size() > 1)
m_currentTimings->reserveCapacity(m_timingsVector->begin()->size());
SnapshotPlayer::play();
now = WTF::monotonicallyIncreasingTime();
m_currentTimings->append(now);
}
}
virtual bool abortDrawing() OVERRIDE
{
m_currentTimings->append(WTF::monotonicallyIncreasingTime());
return false;
}
const GraphicsContextSnapshot::Timings& timingsVector() const { return *m_timingsVector; }
private:
GraphicsContextSnapshot::Timings* m_timingsVector;
Vector<double>* m_currentTimings;
};
PassOwnPtr<ImageBuffer> GraphicsContextSnapshot::replay(unsigned fromStep, unsigned toStep) const
{
OwnPtr<ImageBuffer> imageBuffer = createImageBuffer();
FragmentSnapshotPlayer player(m_picture, imageBuffer->context()->canvas());
player.play(fromStep, toStep);
return imageBuffer.release();
}
PassOwnPtr<GraphicsContextSnapshot::Timings> GraphicsContextSnapshot::profile(unsigned minRepeatCount, double minDuration) const
{
OwnPtr<GraphicsContextSnapshot::Timings> timings = adoptPtr(new GraphicsContextSnapshot::Timings());
OwnPtr<ImageBuffer> imageBuffer = createImageBuffer();
ProfilingSnapshotPlayer player(m_picture, imageBuffer->context()->canvas());
player.play(timings.get(), minRepeatCount, minDuration);
return timings.release();
}
PassOwnPtr<ImageBuffer> GraphicsContextSnapshot::createImageBuffer() const
{
return ImageBuffer::create(IntSize(m_picture->width(), m_picture->height()), m_isCertainlyOpaque ? Opaque : NonOpaque);
}
}