|  | // Copyright (c) 2012 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_COMMAND_EXECUTOR_H_ | 
|  | #define GPU_COMMAND_BUFFER_SERVICE_COMMAND_EXECUTOR_H_ | 
|  |  | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <memory> | 
|  | #include <queue> | 
|  |  | 
|  | #include "base/atomic_ref_count.h" | 
|  | #include "base/atomicops.h" | 
|  | #include "base/callback.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/memory/ref_counted.h" | 
|  | #include "base/memory/shared_memory.h" | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 
|  | #include "gpu/command_buffer/service/cmd_parser.h" | 
|  | #include "gpu/command_buffer/service/command_buffer_service.h" | 
|  | #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 
|  | #include "gpu/gpu_export.h" | 
|  |  | 
|  | namespace gpu { | 
|  |  | 
|  | class PreemptionFlag : public base::RefCountedThreadSafe<PreemptionFlag> { | 
|  | public: | 
|  | PreemptionFlag() : flag_(0) {} | 
|  |  | 
|  | bool IsSet() { return !base::AtomicRefCountIsZero(&flag_); } | 
|  | void Set() { base::AtomicRefCountInc(&flag_); } | 
|  | void Reset() { base::subtle::NoBarrier_Store(&flag_, 0); } | 
|  |  | 
|  | private: | 
|  | base::AtomicRefCount flag_; | 
|  |  | 
|  | ~PreemptionFlag() {} | 
|  |  | 
|  | friend class base::RefCountedThreadSafe<PreemptionFlag>; | 
|  | }; | 
|  |  | 
|  | // This class schedules commands that have been flushed. They are received via | 
|  | // a command buffer and forwarded to a command parser. TODO(apatrick): This | 
|  | // class should not know about the decoder. Do not add additional dependencies | 
|  | // on it. | 
|  | class GPU_EXPORT CommandExecutor | 
|  | : NON_EXPORTED_BASE(public CommandBufferEngine), | 
|  | public base::SupportsWeakPtr<CommandExecutor> { | 
|  | public: | 
|  | CommandExecutor(CommandBufferServiceBase* command_buffer, | 
|  | AsyncAPIInterface* handler, | 
|  | gles2::GLES2Decoder* decoder); | 
|  |  | 
|  | ~CommandExecutor() override; | 
|  |  | 
|  | void PutChanged(); | 
|  |  | 
|  | void SetPreemptByFlag(scoped_refptr<PreemptionFlag> flag) { | 
|  | preemption_flag_ = flag; | 
|  | } | 
|  |  | 
|  | // Sets whether commands should be processed by this scheduler. Setting to | 
|  | // false unschedules. Setting to true reschedules. | 
|  | void SetScheduled(bool scheduled); | 
|  |  | 
|  | bool scheduled() const { return scheduled_; } | 
|  |  | 
|  | // Returns whether the scheduler needs to be polled again in the future to | 
|  | // process pending queries. | 
|  | bool HasPendingQueries() const; | 
|  |  | 
|  | // Process pending queries and return. HasPendingQueries() can be used to | 
|  | // determine if there's more pending queries after this has been called. | 
|  | void ProcessPendingQueries(); | 
|  |  | 
|  | // Implementation of CommandBufferEngine. | 
|  | scoped_refptr<Buffer> GetSharedMemoryBuffer(int32_t shm_id) override; | 
|  | void set_token(int32_t token) override; | 
|  | bool SetGetBuffer(int32_t transfer_buffer_id) override; | 
|  | bool SetGetOffset(int32_t offset) override; | 
|  | int32_t GetGetOffset() override; | 
|  |  | 
|  | void SetCommandProcessedCallback(const base::Closure& callback); | 
|  |  | 
|  | // Returns whether the scheduler needs to be polled again in the future to | 
|  | // process idle work. | 
|  | bool HasMoreIdleWork() const; | 
|  |  | 
|  | // Perform some idle work and return. HasMoreIdleWork() can be used to | 
|  | // determine if there's more idle work do be done after this has been called. | 
|  | void PerformIdleWork(); | 
|  |  | 
|  | // Whether there is state that needs to be regularly polled. | 
|  | bool HasPollingWork() const; | 
|  | void PerformPollingWork(); | 
|  |  | 
|  | CommandParser* parser() const { return parser_.get(); } | 
|  |  | 
|  | private: | 
|  | bool IsPreempted(); | 
|  |  | 
|  | // The CommandExecutor holds a weak reference to the CommandBuffer. The | 
|  | // CommandBuffer owns the CommandExecutor and holds a strong reference to it | 
|  | // through the ProcessCommands callback. | 
|  | CommandBufferServiceBase* command_buffer_; | 
|  |  | 
|  | // The parser uses this to execute commands. | 
|  | AsyncAPIInterface* handler_; | 
|  |  | 
|  | // Does not own decoder. TODO(apatrick): The CommandExecutor shouldn't need a | 
|  | // pointer to the decoder, it is only used to initialize the CommandParser, | 
|  | // which could be an argument to the constructor, and to determine the | 
|  | // reason for context lost. | 
|  | gles2::GLES2Decoder* decoder_; | 
|  |  | 
|  | // TODO(apatrick): The CommandExecutor currently creates and owns the parser. | 
|  | // This should be an argument to the constructor. | 
|  | std::unique_ptr<CommandParser> parser_; | 
|  |  | 
|  | // Whether the scheduler is currently able to process more commands. | 
|  | bool scheduled_; | 
|  |  | 
|  | base::Closure command_processed_callback_; | 
|  |  | 
|  | // If non-NULL and |preemption_flag_->IsSet()|, exit PutChanged early. | 
|  | scoped_refptr<PreemptionFlag> preemption_flag_; | 
|  | bool was_preempted_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(CommandExecutor); | 
|  | }; | 
|  |  | 
|  | }  // namespace gpu | 
|  |  | 
|  | #endif  // GPU_COMMAND_BUFFER_SERVICE_COMMAND_EXECUTOR_H_ |