author Emilio Cobos Álvarez <>
Fri, 01 Jun 2018 18:30:30 +0200
changeset 420970 bb85c5ee5afc151be0d07ecc48318dc69cfef446
parent 389027 5f74d262924171a8fa0b4483a64f4cac34c4c9b8
child 448947 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1466168: Remove mozilla::Forward in favor of std::forward. r=froydnj Same approach as the other bug, mostly replacing automatically by removing 'using mozilla::Forward;' and then: s/mozilla::Forward/std::forward/ s/Forward</std::forward</ The only file that required manual fixup was TestTreeTraversal.cpp, which had a class called TestNodeForward with template parameters :) MozReview-Commit-ID: A88qFG5AccP

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */


#include <stdint.h>

#include "mozilla/RefPtr.h"
#include "mozilla/Assertions.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/gfx/JobScheduler.h"
#include "mozilla/gfx/IterableArena.h"
#include "mozilla/RefCounted.h"
#include "DrawCommand.h"

namespace mozilla {
namespace gfx {

class DrawingCommand;
class PrintCommand;
class SignalCommand;
class DrawingJob;
class WaitCommand;

class SyncObject;
class MultiThreadedJobQueue;

class DrawTarget;

class DrawingJobBuilder;
class CommandBufferBuilder;

/// Contains a sequence of immutable drawing commands that are typically used by
/// several DrawingJobs.
/// CommandBuffer objects are built using CommandBufferBuilder.
class CommandBuffer : public external::AtomicRefCounted<CommandBuffer>


  const DrawingCommand* GetDrawingCommand(ptrdiff_t aId);

  explicit CommandBuffer(size_t aSize = 256)
  : mStorage(IterableArena::GROWABLE, aSize)

  IterableArena mStorage;
  friend class CommandBufferBuilder;

/// Generates CommandBuffer objects.
/// The builder is a separate object to ensure that commands are not added to a
/// submitted CommandBuffer.
class CommandBufferBuilder
  void BeginCommandBuffer(size_t aBufferSize = 256);

  already_AddRefed<CommandBuffer> EndCommandBuffer();

  /// Build the CommandBuffer, command after command.
  /// This must be used between BeginCommandBuffer and EndCommandBuffer.
  template<typename T, typename... Args>
  ptrdiff_t AddCommand(Args&&... aArgs)
    static_assert(IsBaseOf<DrawingCommand, T>::value,
                  "T must derive from DrawingCommand");
    return mCommands->mStorage.Alloc<T>(std::forward<Args>(aArgs)...);

  bool HasCommands() const { return !!mCommands; }

  RefPtr<CommandBuffer> mCommands;

/// Stores multiple commands to be executed sequencially.
class DrawingJob : public Job {

  virtual JobStatus Run() override;

  DrawingJob(DrawTarget* aTarget,
              IntPoint aOffset,
              SyncObject* aStart,
              SyncObject* aCompletion,
              WorkerThread* aPinToWorker = nullptr);

  /// Runs the tasks's destructors and resets the buffer.
  void Clear();

  std::vector<ptrdiff_t> mCommandOffsets;
  RefPtr<CommandBuffer> mCommandBuffer;
  uint32_t mCursor;

  RefPtr<DrawTarget> mDrawTarget;
  IntPoint mOffset;

  friend class DrawingJobBuilder;

/// Generates DrawingJob objects.
/// The builder is a separate object to ensure that commands are not added to a
/// submitted DrawingJob.
class DrawingJobBuilder {


  /// Allocates a DrawingJob.
  /// call this method before starting to add commands.
  void BeginDrawingJob(DrawTarget* aTarget, IntPoint aOffset,
                        SyncObject* aStart = nullptr);

  /// Build the DrawingJob, command after command.
  /// This must be used between BeginDrawingJob and EndDrawingJob.
  void AddCommand(ptrdiff_t offset)

  /// Finalizes and returns the drawing task.
  /// If aCompletion is not null, the sync object will be signaled after the
  /// task buffer is destroyed (and after the destructor of the tasks have run).
  /// In most cases this means after the completion of all tasks in the task buffer,
  /// but also when the task buffer is destroyed due to an error.
  DrawingJob* EndDrawingJob(CommandBuffer* aCmdBuffer,
                              SyncObject* aCompletion = nullptr,
                              WorkerThread* aPinToWorker = nullptr);

  /// Returns true between BeginDrawingJob and EndDrawingJob, false otherwise.
  bool HasDrawingJob() const { return !!mDrawTarget; }

  std::vector<ptrdiff_t> mCommandOffsets;
  RefPtr<DrawTarget> mDrawTarget;
  IntPoint mOffset;
  RefPtr<SyncObject> mStart;

} // namespace
} // namespace