blob: 9bdbd49616d2797d382f53b900ae419802a4ddb7 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
#define GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
#include <vector>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/gpu_export.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gpu_preference.h"
namespace base {
class SequenceChecker;
}
namespace gfx {
class GLContext;
class GLImage;
class GLSurface;
class Size;
}
namespace gpu {
namespace gles2 {
class GLES2Decoder;
}
class GpuScheduler;
class TransferBufferManagerInterface;
// This class provides a thread-safe interface to the global GPU service (for
// example GPU thread) when being run in single process mode.
// However, the behavior for accessing one context (i.e. one instance of this
// class) from different client threads is undefined.
class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer {
public:
InProcessCommandBuffer();
virtual ~InProcessCommandBuffer();
// Used to override the GPU thread with explicit scheduling.
// (By default an internal GPU thread will be spawned to handle all GL work
// and the two functions are unused.)
// The callback will be called from different client threads. After the
// callback is issued, the client is expected to eventually call
// ProcessGpuWorkOnCurrentThread(). The latter cannot be called from different
// threads.
// The callback needs to be set before any context is created.
static void SetScheduleCallback(const base::Closure& callback);
static void ProcessGpuWorkOnCurrentThread();
static void EnableVirtualizedContext();
// If |surface| is not NULL, use it directly; in this case, the command
// buffer gpu thread must be the same as the client thread. Otherwise create
// a new GLSurface.
bool Initialize(scoped_refptr<gfx::GLSurface> surface,
bool is_offscreen,
bool share_resources,
gfx::AcceleratedWidget window,
const gfx::Size& size,
const char* allowed_extensions,
const std::vector<int32>& attribs,
gfx::GpuPreference gpu_preference,
const base::Closure& context_lost_callback,
unsigned int share_group_id);
void Destroy();
void SignalSyncPoint(unsigned sync_point,
const base::Closure& callback);
unsigned int CreateImageForGpuMemoryBuffer(
gfx::GpuMemoryBufferHandle buffer,
gfx::Size size);
void RemoveImage(unsigned int image_id);
// CommandBuffer implementation:
virtual bool Initialize() OVERRIDE;
virtual State GetState() OVERRIDE;
virtual State GetLastState() OVERRIDE;
virtual int32 GetLastToken() OVERRIDE;
virtual void Flush(int32 put_offset) OVERRIDE;
virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE;
virtual void SetGetBuffer(int32 shm_id) OVERRIDE;
virtual void SetGetOffset(int32 get_offset) OVERRIDE;
virtual gpu::Buffer CreateTransferBuffer(size_t size, int32* id) OVERRIDE;
virtual void DestroyTransferBuffer(int32 id) OVERRIDE;
virtual gpu::Buffer GetTransferBuffer(int32 id) OVERRIDE;
virtual void SetToken(int32 token) OVERRIDE;
virtual void SetParseError(gpu::error::Error error) OVERRIDE;
virtual void SetContextLostReason(
gpu::error::ContextLostReason reason) OVERRIDE;
virtual uint32 InsertSyncPoint() OVERRIDE;
virtual gpu::error::Error GetLastError() OVERRIDE;
// The serializer interface to the GPU service (i.e. thread).
class SchedulerClient {
public:
virtual ~SchedulerClient() {}
virtual void QueueTask(const base::Closure& task) = 0;
};
private:
bool InitializeOnGpuThread(bool is_offscreen,
gfx::AcceleratedWidget window,
const gfx::Size& size,
const char* allowed_extensions,
const std::vector<int32>& attribs,
gfx::GpuPreference gpu_preference);
bool DestroyOnGpuThread();
void FlushOnGpuThread(int32 put_offset);
void CreateImageOnGpuThread(gfx::GpuMemoryBufferHandle buffer,
gfx::Size size,
unsigned int image_id);
void RemoveImageOnGpuThread(unsigned int image_id);
bool MakeCurrent();
bool IsContextLost();
base::Closure WrapCallback(const base::Closure& callback);
State GetStateFast();
void QueueTask(const base::Closure& task) { queue_->QueueTask(task); }
void CheckSequencedThread();
// Callbacks:
void OnContextLost();
void OnResizeView(gfx::Size size, float scale_factor);
bool GetBufferChanged(int32 transfer_buffer_id);
void PumpCommands();
// Members accessed on the gpu thread (possibly with the exception of
// creation):
bool context_lost_;
bool share_resources_;
scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
scoped_ptr<GpuScheduler> gpu_scheduler_;
scoped_ptr<gles2::GLES2Decoder> decoder_;
scoped_refptr<gfx::GLContext> context_;
scoped_refptr<gfx::GLSurface> surface_;
base::Closure context_lost_callback_;
unsigned int share_group_id_;
// Members accessed on the client thread:
State last_state_;
int32 last_put_offset_;
// Accessed on both threads:
scoped_ptr<CommandBuffer> command_buffer_;
base::Lock command_buffer_lock_;
base::WaitableEvent flush_event_;
scoped_ptr<SchedulerClient> queue_;
State state_after_last_flush_;
base::Lock state_after_last_flush_lock_;
// Only used with explicit scheduling and the gpu thread is the same as
// the client thread.
scoped_ptr<base::SequenceChecker> sequence_checker_;
DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer);
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_