blob: d86ff3f1dd1ffe8b244bb33d972763cfa7f811cf [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_LIB_UI_GFX_RESOURCES_IMAGE_PIPE_H_
#define GARNET_LIB_UI_GFX_RESOURCES_IMAGE_PIPE_H_
#include <lib/zx/event.h>
#include <lib/zx/vmo.h>
#include <queue>
#include <fuchsia/images/cpp/fidl.h>
#include "garnet/lib/ui/gfx/resources/image.h"
#include "garnet/lib/ui/gfx/resources/image_base.h"
#include "garnet/lib/ui/gfx/resources/image_pipe_handler.h"
#include "garnet/lib/ui/gfx/resources/resource.h"
#include "lib/escher/flib/fence_set_listener.h"
#include "lib/fxl/memory/weak_ptr.h"
namespace scenic_impl {
namespace gfx {
class ImagePipe;
using ImagePipePtr = fxl::RefPtr<ImagePipe>;
class ImagePipe : public ImageBase {
public:
static const ResourceTypeInfo kTypeInfo;
ImagePipe(Session* session, ResourceId id);
ImagePipe(Session* session, ResourceId id,
::fidl::InterfaceRequest<fuchsia::images::ImagePipe> request);
// Called by |ImagePipeHandler|, part of |ImagePipe| interface.
void AddImage(uint32_t image_id, fuchsia::images::ImageInfo image_info,
zx::vmo memory, uint64_t offset_bytes, uint64_t size_bytes,
fuchsia::images::MemoryType memory_type);
void RemoveImage(uint32_t image_id);
void PresentImage(uint32_t image_id, uint64_t presentation_time,
::fidl::VectorPtr<zx::event> acquire_fences,
::fidl::VectorPtr<zx::event> release_fences,
fuchsia::images::ImagePipe::PresentImageCallback callback);
void Accept(class ResourceVisitor* visitor) override;
// Update to use the most current frame for the specified presentation time.
// Called before rendering a frame using this ImagePipe. Return true if the
// current Image changed since the last time Update() was called, and false
// otherwise.
bool Update(uint64_t presentation_time, uint64_t presentation_interval);
// Returns the image that should be presented at the current time. Can be
// null.
const escher::ImagePtr& GetEscherImage() override;
// Returns true if the connection to the ImagePipe has not closed.
bool is_valid() { return is_valid_; };
private:
friend class ImagePipeHandler;
// Called when the image pipe connection is closed.
void OnConnectionError();
// Called when we want to close the connection ourselves. Cleans up resources
// and schedules a new frame update.
void CloseConnectionAndCleanUp();
// Virtual so that test subclasses can override.
virtual ImagePtr CreateImage(Session* session, ResourceId id,
MemoryPtr memory,
const fuchsia::images::ImageInfo& image_info,
uint64_t memory_offset,
ErrorReporter* error_reporter);
fxl::WeakPtrFactory<ImagePipe> weak_ptr_factory_;
// A |Frame| stores the arguments passed to a particular invocation of
// Present().
struct Frame {
ImagePtr image;
uint64_t presentation_time;
std::unique_ptr<escher::FenceSetListener> acquire_fences;
::fidl::VectorPtr<zx::event> release_fences;
// Callback to report when the update has been applied in response to
// an invocation of |ImagePipe.PresentImage()|.
fuchsia::images::ImagePipe::PresentImageCallback present_image_callback;
};
std::queue<Frame> frames_;
std::unique_ptr<ImagePipeHandler> handler_;
ResourceId current_image_id_ = 0;
ImagePtr current_image_;
::fidl::VectorPtr<zx::event> current_release_fences_;
std::unordered_map<ResourceId, ImagePtr> images_;
bool is_valid_ = true;
FXL_DISALLOW_COPY_AND_ASSIGN(ImagePipe);
};
} // namespace gfx
} // namespace scenic_impl
#endif // GARNET_LIB_UI_GFX_RESOURCES_IMAGE_PIPE_H_