ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / device / device.h
index aa0a8e4..15a0ceb 100644 (file)
@@ -40,384 +40,428 @@ class RenderTile;
 /* Device Types */
 
 enum DeviceType {
-       DEVICE_NONE = 0,
-       DEVICE_CPU,
-       DEVICE_OPENCL,
-       DEVICE_CUDA,
-       DEVICE_NETWORK,
-       DEVICE_MULTI
+  DEVICE_NONE = 0,
+  DEVICE_CPU,
+  DEVICE_OPENCL,
+  DEVICE_CUDA,
+  DEVICE_NETWORK,
+  DEVICE_MULTI
 };
 
 enum DeviceTypeMask {
-       DEVICE_MASK_CPU = (1 << DEVICE_CPU),
-       DEVICE_MASK_OPENCL = (1 << DEVICE_OPENCL),
-       DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
-       DEVICE_MASK_NETWORK = (1 << DEVICE_NETWORK),
-       DEVICE_MASK_ALL = ~0
+  DEVICE_MASK_CPU = (1 << DEVICE_CPU),
+  DEVICE_MASK_OPENCL = (1 << DEVICE_OPENCL),
+  DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
+  DEVICE_MASK_NETWORK = (1 << DEVICE_NETWORK),
+  DEVICE_MASK_ALL = ~0
 };
 
 enum DeviceKernelStatus {
-       DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL = 0,
-       DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
-       DEVICE_KERNEL_USING_FEATURE_KERNEL,
-       DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
-       DEVICE_KERNEL_UNKNOWN,
+  DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL = 0,
+  DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
+  DEVICE_KERNEL_USING_FEATURE_KERNEL,
+  DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
+  DEVICE_KERNEL_UNKNOWN,
 };
 
 #define DEVICE_MASK(type) (DeviceTypeMask)(1 << type)
 
 class DeviceInfo {
-public:
-       DeviceType type;
-       string description;
-       string id; /* used for user preferences, should stay fixed with changing hardware config */
-       int num;
-       bool display_device;            /* GPU is used as a display device. */
-       bool has_half_images;           /* Support half-float textures. */
-       bool has_volume_decoupled;      /* Decoupled volume shading. */
-       bool has_osl;                   /* Support Open Shading Language. */
-       bool use_split_kernel;          /* Use split or mega kernel. */
-       bool has_profiling;             /* Supports runtime collection of profiling info. */
-       int cpu_threads;
-       vector<DeviceInfo> multi_devices;
-
-       DeviceInfo()
-       {
-               type = DEVICE_CPU;
-               id = "CPU";
-               num = 0;
-               cpu_threads = 0;
-               display_device = false;
-               has_half_images = false;
-               has_volume_decoupled = false;
-               has_osl = false;
-               use_split_kernel = false;
-               has_profiling = false;
-       }
-
-       bool operator==(const DeviceInfo &info) {
-               /* Multiple Devices with the same ID would be very bad. */
-               assert(id != info.id || (type == info.type && num == info.num && description == info.description));
-               return id == info.id;
-       }
+ public:
+  DeviceType type;
+  string description;
+  string id; /* used for user preferences, should stay fixed with changing hardware config */
+  int num;
+  bool display_device;       /* GPU is used as a display device. */
+  bool has_half_images;      /* Support half-float textures. */
+  bool has_volume_decoupled; /* Decoupled volume shading. */
+  bool has_osl;              /* Support Open Shading Language. */
+  bool use_split_kernel;     /* Use split or mega kernel. */
+  bool has_profiling;        /* Supports runtime collection of profiling info. */
+  int cpu_threads;
+  vector<DeviceInfo> multi_devices;
+
+  DeviceInfo()
+  {
+    type = DEVICE_CPU;
+    id = "CPU";
+    num = 0;
+    cpu_threads = 0;
+    display_device = false;
+    has_half_images = false;
+    has_volume_decoupled = false;
+    has_osl = false;
+    use_split_kernel = false;
+    has_profiling = false;
+  }
+
+  bool operator==(const DeviceInfo &info)
+  {
+    /* Multiple Devices with the same ID would be very bad. */
+    assert(id != info.id ||
+           (type == info.type && num == info.num && description == info.description));
+    return id == info.id;
+  }
 };
 
 class DeviceRequestedFeatures {
-public:
-       /* Use experimental feature set. */
-       bool experimental;
-
-       /* Selective nodes compilation. */
-
-       /* Identifier of a node group up to which all the nodes needs to be
-        * compiled in. Nodes from higher group indices will be ignores.
-        */
-       int max_nodes_group;
-
-       /* Features bitfield indicating which features from the requested group
-        * will be compiled in. Nodes which corresponds to features which are not
-        * in this bitfield will be ignored even if they're in the requested group.
-        */
-       int nodes_features;
-
-       /* BVH/sampling kernel features. */
-       bool use_hair;
-       bool use_object_motion;
-       bool use_camera_motion;
-
-       /* Denotes whether baking functionality is needed. */
-       bool use_baking;
-
-       /* Use subsurface scattering materials. */
-       bool use_subsurface;
-
-       /* Use volume materials. */
-       bool use_volume;
-
-       /* Use branched integrator. */
-       bool use_integrator_branched;
-
-       /* Use OpenSubdiv patch evaluation */
-       bool use_patch_evaluation;
-
-       /* Use Transparent shadows */
-       bool use_transparent;
-
-       /* Use various shadow tricks, such as shadow catcher. */
-       bool use_shadow_tricks;
-
-       /* Per-uber shader usage flags. */
-       bool use_principled;
-
-       /* Denoising features. */
-       bool use_denoising;
-
-       /* Use raytracing in shaders. */
-       bool use_shader_raytrace;
-
-       /* Use true displacement */
-       bool use_true_displacement;
-
-       /* Use background lights */
-       bool use_background_light;
-
-       DeviceRequestedFeatures()
-       {
-               /* TODO(sergey): Find more meaningful defaults. */
-               experimental = false;
-               max_nodes_group = 0;
-               nodes_features = 0;
-               use_hair = false;
-               use_object_motion = false;
-               use_camera_motion = false;
-               use_baking = false;
-               use_subsurface = false;
-               use_volume = false;
-               use_integrator_branched = false;
-               use_patch_evaluation = false;
-               use_transparent = false;
-               use_shadow_tricks = false;
-               use_principled = false;
-               use_denoising = false;
-               use_shader_raytrace = false;
-               use_true_displacement = false;
-               use_background_light = false;
-       }
-
-       bool modified(const DeviceRequestedFeatures& requested_features)
-       {
-               return !(experimental == requested_features.experimental &&
-                        max_nodes_group == requested_features.max_nodes_group &&
-                        nodes_features == requested_features.nodes_features &&
-                        use_hair == requested_features.use_hair &&
-                        use_object_motion == requested_features.use_object_motion &&
-                        use_camera_motion == requested_features.use_camera_motion &&
-                        use_baking == requested_features.use_baking &&
-                        use_subsurface == requested_features.use_subsurface &&
-                        use_volume == requested_features.use_volume &&
-                        use_integrator_branched == requested_features.use_integrator_branched &&
-                        use_patch_evaluation == requested_features.use_patch_evaluation &&
-                        use_transparent == requested_features.use_transparent &&
-                        use_shadow_tricks == requested_features.use_shadow_tricks &&
-                        use_principled == requested_features.use_principled &&
-                        use_denoising == requested_features.use_denoising &&
-                        use_shader_raytrace == requested_features.use_shader_raytrace &&
-                        use_true_displacement == requested_features.use_true_displacement &&
-                        use_background_light == requested_features.use_background_light);
-       }
-
-       /* Convert the requested features structure to a build options,
-        * which could then be passed to compilers.
-        */
-       string get_build_options() const
-       {
-               string build_options = "";
-               if(experimental) {
-                       build_options += "-D__KERNEL_EXPERIMENTAL__ ";
-               }
-               build_options += "-D__NODES_MAX_GROUP__=" +
-                       string_printf("%d", max_nodes_group);
-               build_options += " -D__NODES_FEATURES__=" +
-                       string_printf("%d", nodes_features);
-               if(!use_hair) {
-                       build_options += " -D__NO_HAIR__";
-               }
-               if(!use_object_motion) {
-                       build_options += " -D__NO_OBJECT_MOTION__";
-               }
-               if(!use_camera_motion) {
-                       build_options += " -D__NO_CAMERA_MOTION__";
-               }
-               if(!use_baking) {
-                       build_options += " -D__NO_BAKING__";
-               }
-               if(!use_volume) {
-                       build_options += " -D__NO_VOLUME__";
-               }
-               if(!use_subsurface) {
-                       build_options += " -D__NO_SUBSURFACE__";
-               }
-               if(!use_integrator_branched) {
-                       build_options += " -D__NO_BRANCHED_PATH__";
-               }
-               if(!use_patch_evaluation) {
-                       build_options += " -D__NO_PATCH_EVAL__";
-               }
-               if(!use_transparent && !use_volume) {
-                       build_options += " -D__NO_TRANSPARENT__";
-               }
-               if(!use_shadow_tricks) {
-                       build_options += " -D__NO_SHADOW_TRICKS__";
-               }
-               if(!use_principled) {
-                       build_options += " -D__NO_PRINCIPLED__";
-               }
-               if(!use_denoising) {
-                       build_options += " -D__NO_DENOISING__";
-               }
-               if(!use_shader_raytrace) {
-                       build_options += " -D__NO_SHADER_RAYTRACE__";
-               }
-               return build_options;
-       }
+ public:
+  /* Use experimental feature set. */
+  bool experimental;
+
+  /* Selective nodes compilation. */
+
+  /* Identifier of a node group up to which all the nodes needs to be
+   * compiled in. Nodes from higher group indices will be ignores.
+   */
+  int max_nodes_group;
+
+  /* Features bitfield indicating which features from the requested group
+   * will be compiled in. Nodes which corresponds to features which are not
+   * in this bitfield will be ignored even if they're in the requested group.
+   */
+  int nodes_features;
+
+  /* BVH/sampling kernel features. */
+  bool use_hair;
+  bool use_object_motion;
+  bool use_camera_motion;
+
+  /* Denotes whether baking functionality is needed. */
+  bool use_baking;
+
+  /* Use subsurface scattering materials. */
+  bool use_subsurface;
+
+  /* Use volume materials. */
+  bool use_volume;
+
+  /* Use branched integrator. */
+  bool use_integrator_branched;
+
+  /* Use OpenSubdiv patch evaluation */
+  bool use_patch_evaluation;
+
+  /* Use Transparent shadows */
+  bool use_transparent;
+
+  /* Use various shadow tricks, such as shadow catcher. */
+  bool use_shadow_tricks;
+
+  /* Per-uber shader usage flags. */
+  bool use_principled;
+
+  /* Denoising features. */
+  bool use_denoising;
+
+  /* Use raytracing in shaders. */
+  bool use_shader_raytrace;
+
+  /* Use true displacement */
+  bool use_true_displacement;
+
+  /* Use background lights */
+  bool use_background_light;
+
+  DeviceRequestedFeatures()
+  {
+    /* TODO(sergey): Find more meaningful defaults. */
+    experimental = false;
+    max_nodes_group = 0;
+    nodes_features = 0;
+    use_hair = false;
+    use_object_motion = false;
+    use_camera_motion = false;
+    use_baking = false;
+    use_subsurface = false;
+    use_volume = false;
+    use_integrator_branched = false;
+    use_patch_evaluation = false;
+    use_transparent = false;
+    use_shadow_tricks = false;
+    use_principled = false;
+    use_denoising = false;
+    use_shader_raytrace = false;
+    use_true_displacement = false;
+    use_background_light = false;
+  }
+
+  bool modified(const DeviceRequestedFeatures &requested_features)
+  {
+    return !(experimental == requested_features.experimental &&
+             max_nodes_group == requested_features.max_nodes_group &&
+             nodes_features == requested_features.nodes_features &&
+             use_hair == requested_features.use_hair &&
+             use_object_motion == requested_features.use_object_motion &&
+             use_camera_motion == requested_features.use_camera_motion &&
+             use_baking == requested_features.use_baking &&
+             use_subsurface == requested_features.use_subsurface &&
+             use_volume == requested_features.use_volume &&
+             use_integrator_branched == requested_features.use_integrator_branched &&
+             use_patch_evaluation == requested_features.use_patch_evaluation &&
+             use_transparent == requested_features.use_transparent &&
+             use_shadow_tricks == requested_features.use_shadow_tricks &&
+             use_principled == requested_features.use_principled &&
+             use_denoising == requested_features.use_denoising &&
+             use_shader_raytrace == requested_features.use_shader_raytrace &&
+             use_true_displacement == requested_features.use_true_displacement &&
+             use_background_light == requested_features.use_background_light);
+  }
+
+  /* Convert the requested features structure to a build options,
+   * which could then be passed to compilers.
+   */
+  string get_build_options() const
+  {
+    string build_options = "";
+    if (experimental) {
+      build_options += "-D__KERNEL_EXPERIMENTAL__ ";
+    }
+    build_options += "-D__NODES_MAX_GROUP__=" + string_printf("%d", max_nodes_group);
+    build_options += " -D__NODES_FEATURES__=" + string_printf("%d", nodes_features);
+    if (!use_hair) {
+      build_options += " -D__NO_HAIR__";
+    }
+    if (!use_object_motion) {
+      build_options += " -D__NO_OBJECT_MOTION__";
+    }
+    if (!use_camera_motion) {
+      build_options += " -D__NO_CAMERA_MOTION__";
+    }
+    if (!use_baking) {
+      build_options += " -D__NO_BAKING__";
+    }
+    if (!use_volume) {
+      build_options += " -D__NO_VOLUME__";
+    }
+    if (!use_subsurface) {
+      build_options += " -D__NO_SUBSURFACE__";
+    }
+    if (!use_integrator_branched) {
+      build_options += " -D__NO_BRANCHED_PATH__";
+    }
+    if (!use_patch_evaluation) {
+      build_options += " -D__NO_PATCH_EVAL__";
+    }
+    if (!use_transparent && !use_volume) {
+      build_options += " -D__NO_TRANSPARENT__";
+    }
+    if (!use_shadow_tricks) {
+      build_options += " -D__NO_SHADOW_TRICKS__";
+    }
+    if (!use_principled) {
+      build_options += " -D__NO_PRINCIPLED__";
+    }
+    if (!use_denoising) {
+      build_options += " -D__NO_DENOISING__";
+    }
+    if (!use_shader_raytrace) {
+      build_options += " -D__NO_SHADER_RAYTRACE__";
+    }
+    return build_options;
+  }
 };
 
-std::ostream& operator <<(std::ostream &os,
-                          const DeviceRequestedFeatures& requested_features);
+std::ostream &operator<<(std::ostream &os, const DeviceRequestedFeatures &requested_features);
 
 /* Device */
 
 struct DeviceDrawParams {
-       function<void()> bind_display_space_shader_cb;
-       function<void()> unbind_display_space_shader_cb;
+  function<void()> bind_display_space_shader_cb;
+  function<void()> unbind_display_space_shader_cb;
 };
 
 class Device {
-       friend class device_sub_ptr;
-protected:
-       enum {
-               FALLBACK_SHADER_STATUS_NONE = 0,
-               FALLBACK_SHADER_STATUS_ERROR,
-               FALLBACK_SHADER_STATUS_SUCCESS,
-       };
-
-       Device(DeviceInfo& info_, Stats &stats_, Profiler &profiler_, bool background) : background(background),
-           vertex_buffer(0),
-           fallback_status(FALLBACK_SHADER_STATUS_NONE), fallback_shader_program(0),
-           info(info_), stats(stats_), profiler(profiler_) {}
-
-       bool background;
-       string error_msg;
-
-       /* used for real time display */
-       unsigned int vertex_buffer;
-       int fallback_status, fallback_shader_program;
-       int image_texture_location, fullscreen_location;
-
-       bool bind_fallback_display_space_shader(const float width, const float height);
-
-       virtual device_ptr mem_alloc_sub_ptr(device_memory& /*mem*/, int /*offset*/, int /*size*/)
-       {
-               /* Only required for devices that implement denoising. */
-               assert(false);
-               return (device_ptr) 0;
-       }
-       virtual void mem_free_sub_ptr(device_ptr /*ptr*/) {};
-
-public:
-       virtual ~Device();
-
-       /* info */
-       DeviceInfo info;
-       virtual const string& error_message() { return error_msg; }
-       bool have_error() { return !error_message().empty(); }
-       virtual void set_error(const string& error)
-       {
-               if(!have_error()) {
-                       error_msg = error;
-               }
-               fprintf(stderr, "%s\n", error.c_str());
-               fflush(stderr);
-       }
-       virtual bool show_samples() const { return false; }
-       virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
-
-       /* statistics */
-       Stats &stats;
-       Profiler &profiler;
-
-       /* memory alignment */
-       virtual int mem_sub_ptr_alignment() { return MIN_ALIGNMENT_CPU_DATA_TYPES; }
-
-       /* constant memory */
-       virtual void const_copy_to(const char *name, void *host, size_t size) = 0;
-
-       /* open shading language, only for CPU device */
-       virtual void *osl_memory() { return NULL; }
-
-       /* load/compile kernels, must be called before adding tasks */
-       virtual bool load_kernels(
-               const DeviceRequestedFeatures& /*requested_features*/)
-       { return true; }
-
-       /* Wait for device to become available to upload data and receive tasks
-        * This method is used by the OpenCL device to load the
-        * optimized kernels or when not (yet) available load the
-        * generic kernels (only during foreground rendering) */
-       virtual bool wait_for_availability(
-               const DeviceRequestedFeatures& /*requested_features*/)
-       { return true; }
-       /* Check if there are 'better' kernels available to be used
-        * We can switch over to these kernels
-        * This method is used to determine if we can switch the preview kernels
-        * to regular kernels */
-       virtual DeviceKernelStatus get_active_kernel_switch_state()
-       { return DEVICE_KERNEL_USING_FEATURE_KERNEL; }
-
-       /* tasks */
-       virtual int get_split_task_count(DeviceTask& task) = 0;
-       virtual void task_add(DeviceTask& task) = 0;
-       virtual void task_wait() = 0;
-       virtual void task_cancel() = 0;
-
-       /* opengl drawing */
-       virtual void draw_pixels(device_memory& mem, int y,
-           int w, int h, int width, int height,
-           int dx, int dy, int dw, int dh,
-           bool transparent, const DeviceDrawParams &draw_params);
+  friend class device_sub_ptr;
+
+ protected:
+  enum {
+    FALLBACK_SHADER_STATUS_NONE = 0,
+    FALLBACK_SHADER_STATUS_ERROR,
+    FALLBACK_SHADER_STATUS_SUCCESS,
+  };
+
+  Device(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background)
+      : background(background),
+        vertex_buffer(0),
+        fallback_status(FALLBACK_SHADER_STATUS_NONE),
+        fallback_shader_program(0),
+        info(info_),
+        stats(stats_),
+        profiler(profiler_)
+  {
+  }
+
+  bool background;
+  string error_msg;
+
+  /* used for real time display */
+  unsigned int vertex_buffer;
+  int fallback_status, fallback_shader_program;
+  int image_texture_location, fullscreen_location;
+
+  bool bind_fallback_display_space_shader(const float width, const float height);
+
+  virtual device_ptr mem_alloc_sub_ptr(device_memory & /*mem*/, int /*offset*/, int /*size*/)
+  {
+    /* Only required for devices that implement denoising. */
+    assert(false);
+    return (device_ptr)0;
+  }
+  virtual void mem_free_sub_ptr(device_ptr /*ptr*/){};
+
+ public:
+  virtual ~Device();
+
+  /* info */
+  DeviceInfo info;
+  virtual const string &error_message()
+  {
+    return error_msg;
+  }
+  bool have_error()
+  {
+    return !error_message().empty();
+  }
+  virtual void set_error(const string &error)
+  {
+    if (!have_error()) {
+      error_msg = error;
+    }
+    fprintf(stderr, "%s\n", error.c_str());
+    fflush(stderr);
+  }
+  virtual bool show_samples() const
+  {
+    return false;
+  }
+  virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
+
+  /* statistics */
+  Stats &stats;
+  Profiler &profiler;
+
+  /* memory alignment */
+  virtual int mem_sub_ptr_alignment()
+  {
+    return MIN_ALIGNMENT_CPU_DATA_TYPES;
+  }
+
+  /* constant memory */
+  virtual void const_copy_to(const char *name, void *host, size_t size) = 0;
+
+  /* open shading language, only for CPU device */
+  virtual void *osl_memory()
+  {
+    return NULL;
+  }
+
+  /* load/compile kernels, must be called before adding tasks */
+  virtual bool load_kernels(const DeviceRequestedFeatures & /*requested_features*/)
+  {
+    return true;
+  }
+
+  /* Wait for device to become available to upload data and receive tasks
+   * This method is used by the OpenCL device to load the
+   * optimized kernels or when not (yet) available load the
+   * generic kernels (only during foreground rendering) */
+  virtual bool wait_for_availability(const DeviceRequestedFeatures & /*requested_features*/)
+  {
+    return true;
+  }
+  /* Check if there are 'better' kernels available to be used
+   * We can switch over to these kernels
+   * This method is used to determine if we can switch the preview kernels
+   * to regular kernels */
+  virtual DeviceKernelStatus get_active_kernel_switch_state()
+  {
+    return DEVICE_KERNEL_USING_FEATURE_KERNEL;
+  }
+
+  /* tasks */
+  virtual int get_split_task_count(DeviceTask &task) = 0;
+  virtual void task_add(DeviceTask &task) = 0;
+  virtual void task_wait() = 0;
+  virtual void task_cancel() = 0;
+
+  /* opengl drawing */
+  virtual void draw_pixels(device_memory &mem,
+                           int y,
+                           int w,
+                           int h,
+                           int width,
+                           int height,
+                           int dx,
+                           int dy,
+                           int dw,
+                           int dh,
+                           bool transparent,
+                           const DeviceDrawParams &draw_params);
 
 #ifdef WITH_NETWORK
-       /* networking */
-       void server_run();
+  /* networking */
+  void server_run();
 #endif
 
-       /* multi device */
-       virtual void map_tile(Device * /*sub_device*/, RenderTile& /*tile*/) {}
-       virtual int device_number(Device * /*sub_device*/) { return 0; }
-       virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/) {}
-       virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/) {}
-
-       /* static */
-       static Device *create(DeviceInfo& info, Stats &stats, Profiler& profiler, bool background = true);
-
-       static DeviceType type_from_string(const char *name);
-       static string string_from_type(DeviceType type);
-       static vector<DeviceType> available_types();
-       static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
-       static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
-       static DeviceInfo get_multi_device(const vector<DeviceInfo>& subdevices,
-                                          int threads,
-                                          bool background);
-
-       /* Tag devices lists for update. */
-       static void tag_update();
-
-       static void free_memory();
-
-protected:
-       /* Memory allocation, only accessed through device_memory. */
-       friend class MultiDevice;
-       friend class DeviceServer;
-       friend class device_memory;
-
-       virtual void mem_alloc(device_memory& mem) = 0;
-       virtual void mem_copy_to(device_memory& mem) = 0;
-       virtual void mem_copy_from(device_memory& mem,
-               int y, int w, int h, int elem) = 0;
-       virtual void mem_zero(device_memory& mem) = 0;
-       virtual void mem_free(device_memory& mem) = 0;
-
-private:
-       /* Indicted whether device types and devices lists were initialized. */
-       static bool need_types_update, need_devices_update;
-       static thread_mutex device_mutex;
-       static vector<DeviceInfo> cuda_devices;
-       static vector<DeviceInfo> opencl_devices;
-       static vector<DeviceInfo> cpu_devices;
-       static vector<DeviceInfo> network_devices;
-       static uint devices_initialized_mask;
+  /* multi device */
+  virtual void map_tile(Device * /*sub_device*/, RenderTile & /*tile*/)
+  {
+  }
+  virtual int device_number(Device * /*sub_device*/)
+  {
+    return 0;
+  }
+  virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/)
+  {
+  }
+  virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTile * /*tiles*/)
+  {
+  }
+
+  /* static */
+  static Device *create(DeviceInfo &info,
+                        Stats &stats,
+                        Profiler &profiler,
+                        bool background = true);
+
+  static DeviceType type_from_string(const char *name);
+  static string string_from_type(DeviceType type);
+  static vector<DeviceType> available_types();
+  static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
+  static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
+  static DeviceInfo get_multi_device(const vector<DeviceInfo> &subdevices,
+                                     int threads,
+                                     bool background);
+
+  /* Tag devices lists for update. */
+  static void tag_update();
+
+  static void free_memory();
+
+ protected:
+  /* Memory allocation, only accessed through device_memory. */
+  friend class MultiDevice;
+  friend class DeviceServer;
+  friend class device_memory;
+
+  virtual void mem_alloc(device_memory &mem) = 0;
+  virtual void mem_copy_to(device_memory &mem) = 0;
+  virtual void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) = 0;
+  virtual void mem_zero(device_memory &mem) = 0;
+  virtual void mem_free(device_memory &mem) = 0;
+
+ private:
+  /* Indicted whether device types and devices lists were initialized. */
+  static bool need_types_update, need_devices_update;
+  static thread_mutex device_mutex;
+  static vector<DeviceInfo> cuda_devices;
+  static vector<DeviceInfo> opencl_devices;
+  static vector<DeviceInfo> cpu_devices;
+  static vector<DeviceInfo> network_devices;
+  static uint devices_initialized_mask;
 };
 
 CCL_NAMESPACE_END
 
-#endif  /* __DEVICE_H__ */
+#endif /* __DEVICE_H__ */