mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
151 lines
4.9 KiB
C++
151 lines
4.9 KiB
C++
// 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_GPU_SCHEDULER_H_
|
|
#define GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_H_
|
|
|
|
#include <queue>
|
|
|
|
#include "base/atomic_ref_count.h"
|
|
#include "base/atomicops.h"
|
|
#include "base/callback.h"
|
|
#include "base/memory/linked_ptr.h"
|
|
#include "base/memory/ref_counted.h"
|
|
#include "base/memory/scoped_ptr.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 gfx {
|
|
class GLFence;
|
|
}
|
|
|
|
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 GpuScheduler
|
|
: NON_EXPORTED_BASE(public CommandBufferEngine),
|
|
public base::SupportsWeakPtr<GpuScheduler> {
|
|
public:
|
|
GpuScheduler(CommandBufferServiceBase* command_buffer,
|
|
AsyncAPIInterface* handler,
|
|
gles2::GLES2Decoder* decoder);
|
|
|
|
~GpuScheduler() 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. Whether or not the
|
|
// scheduler is currently scheduled is "reference counted". Every call with
|
|
// false must eventually be paired by a call with true.
|
|
void SetScheduled(bool is_scheduled);
|
|
|
|
// Returns whether the scheduler is currently able to process more commands.
|
|
bool IsScheduled();
|
|
|
|
// Returns whether the scheduler needs to be polled again in the future.
|
|
bool HasMoreWork();
|
|
|
|
typedef base::Callback<void(bool /* scheduled */)> SchedulingChangedCallback;
|
|
|
|
// Sets a callback that is invoked just before scheduler is rescheduled
|
|
// or descheduled. Takes ownership of callback object.
|
|
void SetSchedulingChangedCallback(const SchedulingChangedCallback& callback);
|
|
|
|
// Implementation of CommandBufferEngine.
|
|
scoped_refptr<Buffer> GetSharedMemoryBuffer(int32 shm_id) override;
|
|
void set_token(int32 token) override;
|
|
bool SetGetBuffer(int32 transfer_buffer_id) override;
|
|
bool SetGetOffset(int32 offset) override;
|
|
int32 GetGetOffset() override;
|
|
|
|
void SetCommandProcessedCallback(const base::Closure& callback);
|
|
|
|
bool HasMoreIdleWork();
|
|
void PerformIdleWork();
|
|
|
|
CommandParser* parser() const {
|
|
return parser_.get();
|
|
}
|
|
|
|
bool IsPreempted();
|
|
|
|
private:
|
|
// Artificially reschedule if the scheduler is still unscheduled after a
|
|
// timeout.
|
|
void RescheduleTimeOut();
|
|
|
|
// The GpuScheduler holds a weak reference to the CommandBuffer. The
|
|
// CommandBuffer owns the GpuScheduler 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 GpuScheduler 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 GpuScheduler currently creates and owns the parser.
|
|
// This should be an argument to the constructor.
|
|
scoped_ptr<CommandParser> parser_;
|
|
|
|
// Greater than zero if this is waiting to be rescheduled before continuing.
|
|
int unscheduled_count_;
|
|
|
|
// The number of times this scheduler has been artificially rescheduled on
|
|
// account of a timeout.
|
|
int rescheduled_count_;
|
|
|
|
SchedulingChangedCallback scheduling_changed_callback_;
|
|
base::Closure descheduled_callback_;
|
|
base::Closure command_processed_callback_;
|
|
|
|
// If non-NULL and |preemption_flag_->IsSet()|, exit PutChanged early.
|
|
scoped_refptr<PreemptionFlag> preemption_flag_;
|
|
bool was_preempted_;
|
|
|
|
// A factory for outstanding rescheduling tasks that is invalidated whenever
|
|
// the scheduler is rescheduled.
|
|
base::WeakPtrFactory<GpuScheduler> reschedule_task_factory_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(GpuScheduler);
|
|
};
|
|
|
|
} // namespace gpu
|
|
|
|
#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_H_
|