blob: 7f712d9ecc09d571cc0ccadd284371f0ecf190cb [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 GARNET_EXAMPLES_UI_SHADERTOY_SERVICE_SHADERTOY_STATE_H_
#define GARNET_EXAMPLES_UI_SHADERTOY_SERVICE_SHADERTOY_STATE_H_
#include <fuchsia/examples/shadertoy/cpp/fidl.h>
#include <fuchsia/images/cpp/fidl.h>
#include <zx/eventpair.h>
#include "garnet/examples/ui/shadertoy/service/glm_hack.h"
#include "lib/escher/escher.h"
#include "lib/escher/resources/resource.h"
#include "lib/escher/util/stopwatch.h"
#include "lib/fxl/memory/ref_counted.h"
#include "lib/fxl/memory/weak_ptr.h"
namespace shadertoy {
class Compiler;
class Pipeline;
class Renderer;
class App;
using PipelinePtr = fxl::RefPtr<Pipeline>;
// Core implementation of the Shadertoy API. Subclasses must provide some
// functionality, such as the method for obtaining a framebuffer to render into.
class ShadertoyState : public escher::Resource {
public:
// Factory constructor.
static fxl::RefPtr<ShadertoyState> NewForImagePipe(
App* app, fidl::InterfaceHandle<fuchsia::images::ImagePipe> image_pipe);
// Factory constructor.
static fxl::RefPtr<ShadertoyState> NewForView(App* app,
zx::eventpair view_token,
bool handle_input_events);
virtual ~ShadertoyState();
void SetPaused(bool paused);
void SetShaderCode(
fidl::StringPtr glsl,
fuchsia::examples::shadertoy::Shadertoy::SetShaderCodeCallback callback);
void SetResolution(uint32_t width, uint32_t height);
void SetMouse(glm::vec4 i_mouse);
void SetImage(uint32_t channel,
fidl::InterfaceRequest<fuchsia::images::ImagePipe> request);
protected:
explicit ShadertoyState(App* app);
// Tell the app to close the connection to this Shadertoy, and destroy it.
void Close();
// Subclasses must call this from DrawFrame().
void OnFramePresented(fuchsia::images::PresentationInfo info);
uint32_t width() const { return width_; }
uint32_t height() const { return height_; }
escher::Escher* escher() const { return escher_.get(); }
Renderer* renderer() const { return renderer_; }
const PipelinePtr& pipeline() const { return pipeline_; }
escher::Texture* channel0() const { return nullptr; }
escher::Texture* channel1() const { return nullptr; }
escher::Texture* channel2() const { return nullptr; }
escher::Texture* channel3() const { return nullptr; }
glm::vec4 i_mouse() const { return i_mouse_; }
fxl::WeakPtrFactory<ShadertoyState>* weak_ptr_factory() {
return &weak_ptr_factory_;
}
private:
// Subclasses must implement this, and call OnFramePresented() from it.
virtual void DrawFrame(uint64_t presentation_time, float animation_time) = 0;
// Requests a frame to be drawn.
void RequestFrame(uint64_t presentation_time);
// Subclasses must implement this to react when the resolution changes.
virtual void OnSetResolution() = 0;
static constexpr uint32_t kMaxWidth = 2048;
static constexpr uint32_t kMaxHeight = 2048;
App* const app_;
const escher::EscherWeakPtr escher_;
Compiler* const compiler_;
Renderer* const renderer_;
fxl::WeakPtrFactory<ShadertoyState> weak_ptr_factory_;
PipelinePtr pipeline_;
uint32_t width_ = 0;
uint32_t height_ = 0;
glm::vec4 i_mouse_ = {0, 0, 0, 0};
bool is_paused_ = true;
bool is_drawing_ = false;
bool is_closed_ = false;
escher::Stopwatch stopwatch_;
};
} // namespace shadertoy
#endif // GARNET_EXAMPLES_UI_SHADERTOY_SERVICE_SHADERTOY_STATE_H_