blob: eca29663fa4b8b5758d2442a167f9609ae721cf1 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "OpenglRender/RenderChannel.h"
#include "RendererImpl.h"
#include "android/base/Compiler.h"
#include "android/base/synchronization/Lock.h"
#include "android/base/synchronization/MessageChannel.h"
#include <atomic>
#include <memory>
namespace emugl {
class RenderChannelImpl final : public RenderChannel {
public:
RenderChannelImpl(std::shared_ptr<RendererImpl> renderer);
public:
// RenderChannel implementation, operations provided for a guest system
virtual void setEventCallback(EventCallback callback) override final;
virtual bool write(ChannelBuffer&& buffer) override final;
virtual bool read(ChannelBuffer* buffer, CallType type) override final;
virtual State currentState() const override final {
return mState.load(std::memory_order_acquire);
}
virtual void stop() override final;
virtual bool isStopped() const override final;
public:
// These functions are for the RenderThread, they could be called in
// parallel with the ones from the RenderChannel interface. Make sure the
// internal state remains consistent all the time.
void writeToGuest(ChannelBuffer&& buf);
size_t readFromGuest(ChannelBuffer::value_type* buf, size_t size,
bool blocking);
void forceStop();
private:
DISALLOW_COPY_ASSIGN_AND_MOVE(RenderChannelImpl);
private:
void onEvent(bool byGuest);
State calcState() const;
void stop(bool byGuest);
private:
std::shared_ptr<RendererImpl> mRenderer;
EventCallback mOnEvent;
// Protects the state recalculation and writes to mState.
//
// The correctness condition governing the relationship between mFromGuest,
// mToGuest, and mState is that we can't reach a potentially stable state
// (i.e., at the end of a set of invocations of publically-visible
// operations) in which either:
// - mFromGuest().size() < mFromGuest.capacity(), yet state does not have
// State::CanWrite, or
// - mToGuest().size > 0, yet state does not have State::CanRead.
// Clients assume they can poll currentState() and have the indicate whether
// a write or read might possibly succeed, and this correctness condition
// makes that assumption valid -- if a write or read might succeed,
// mState is required to eventually indicate this.
android::base::Lock mStateLock;
std::atomic<State> mState;
bool mStopped = false;
android::base::MessageChannel<ChannelBuffer, 1024> mFromGuest;
android::base::MessageChannel<ChannelBuffer, 16> mToGuest;
ChannelBuffer mFromGuestBuffer;
size_t mFromGuestBufferLeft = 0;
};
} // namespace emugl