Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  WebGLCommandQueue.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef WEBGLCOMMANDQUEUE_H_
#define WEBGLCOMMANDQUEUE_H_

#include <type_traits>
#include "mozilla/FunctionTypeTraits.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/ipc/IPDLParamTraits.h"
#include "QueueParamTraits.h"
#include "WebGLTypes.h"

namespace mozilla {

namespace webgl {

class RangeConsumerView final : public webgl::ConsumerView<RangeConsumerView> {
  RangedPtr<const uint8_t> mSrcItr;
  const RangedPtr<const uint8_t> mSrcEnd;

 public:
  auto Remaining() const { return *MaybeAs<size_t>(mSrcEnd - mSrcItr); }

  explicit RangeConsumerView(const Range<const uint8_t> range)
      : ConsumerView(this), mSrcItr(range.begin()), mSrcEnd(range.end()) {
    (void)Remaining();  // assert size non-negative
  }

  void AlignTo(const size_t alignment) {
    const auto padToAlign = AlignmentOffset(alignment, mSrcItr.get());
    if (MOZ_UNLIKELY(padToAlign > Remaining())) {
      mSrcItr = mSrcEnd;
      return;
    }
    mSrcItr += padToAlign;
  }

  template <typename T>
  Maybe<Range<const T>> ReadRange(const size_t elemCount) {
    constexpr auto alignment = alignof(T);
    AlignTo(alignment);

    constexpr auto elemSize = sizeof(T);
    const auto byteSizeChecked = CheckedInt<size_t>(elemCount) * elemSize;
    MOZ_RELEASE_ASSERT(byteSizeChecked.isValid());
    const auto& byteSize = byteSizeChecked.value();

    const auto remaining = Remaining();
    if (MOZ_UNLIKELY(byteSize > remaining)) return {};

    const auto begin = reinterpret_cast<const T*>(mSrcItr.get());
    mSrcItr += byteSize;
    return Some(Range<const T>{begin, elemCount});
  }
};

// -

namespace details {

class SizeOnlyProducerView final
    : public webgl::ProducerView<SizeOnlyProducerView> {
  struct Info {
    size_t requiredByteCount = 0;
    size_t alignmentOverhead = 0;
  };
  Info mInfo;

 public:
  SizeOnlyProducerView() : ProducerView(this) {}

  template <typename T>
  bool WriteFromRange(const Range<const T>& src) {
    constexpr auto alignment = alignof(T);
    const size_t byteSize = ByteSize(src);
    // printf_stderr("SizeOnlyProducerView: @%zu +%zu\n", alignment, byteSize);

    const auto padToAlign = AlignmentOffset(alignment, mInfo.requiredByteCount);
    mInfo.alignmentOverhead += padToAlign;

    mInfo.requiredByteCount += padToAlign;
    mInfo.requiredByteCount += byteSize;
    return true;
  }

  const auto& Info() const { return mInfo; }
};

// -

class RangeProducerView final : public webgl::ProducerView<RangeProducerView> {
  const RangedPtr<uint8_t> mDestBegin;
  const RangedPtr<uint8_t> mDestEnd;
  RangedPtr<uint8_t> mDestItr;

 public:
  auto Remaining() const { return *MaybeAs<size_t>(mDestEnd - mDestItr); }

  explicit RangeProducerView(const Range<uint8_t> range)
      : ProducerView(this),
        mDestBegin(range.begin()),
        mDestEnd(range.end()),
        mDestItr(mDestBegin) {
    (void)Remaining();  // assert size non-negative
  }

  template <typename T>
  bool WriteFromRange(const Range<const T>& src) {
    // uint32_t/float data may masquerade as a Range<uint8_t>.
    constexpr auto alignment = alignof(T);
    const size_t byteSize = ByteSize(src);
    // printf_stderr("RangeProducerView: @%zu +%zu\n", alignment, byteSize);

    const auto padToAlign = AlignmentOffset(alignment, mDestItr.get());
    mDestItr += padToAlign;

    MOZ_ASSERT(byteSize <= Remaining());
    if (MOZ_LIKELY(byteSize)) {
      memcpy(mDestItr.get(), src.begin().get(), byteSize);
    }
    mDestItr += byteSize;
    return true;
  }
};

// -

template <typename ProducerViewT>
inline void Serialize(ProducerViewT&) {}

template <typename ProducerViewT, typename Arg, typename... Args>
inline void Serialize(ProducerViewT& view, const Arg& arg,
                      const Args&... args) {
  MOZ_ALWAYS_TRUE(view.WriteParam(arg));
  Serialize(view, args...);
}

}  // namespace details

// -

template <typename... Args>
auto SerializationInfo(const Args&... args) {
  webgl::details::SizeOnlyProducerView sizeView;
  webgl::details::Serialize(sizeView, args...);
  return sizeView.Info();
}

template <typename... Args>
void Serialize(Range<uint8_t> dest, const Args&... args) {
  webgl::details::RangeProducerView view(dest);
  webgl::details::Serialize(view, args...);
}

// -

inline Maybe<uint16_t> Deserialize(RangeConsumerView&, size_t) { return {}; }

template <typename Arg, typename... Args>
inline Maybe<uint16_t> Deserialize(RangeConsumerView& view,
                                   const uint16_t argId, Arg& arg,
                                   Args&... args) {
  if (!webgl::QueueParamTraits<Arg>::Read(view, &arg)) {
    return Some(argId);
  }
  return Deserialize(view, argId + 1, args...);
}

}  // namespace webgl

// -

template <class R, class... Args>
using fn_t = R(Args...);

// The MethodDispatcher setup uses a CommandSink to read parameters, call the
// given method using the given synchronization protocol, and provide
// compile-time lookup of the ID by class method.
// To use this system, first define a dispatcher subclass of
// EmptyMethodDispatcher.  This class must be parameterized by command ID.
//
// Example:
// template <size_t id=0> class MyDispatcher
//    : public EmptyMethodDispatcher<MyDispatcher> {};
//
// Then, for each command handled, specialize this to subclass MethodDispatcher.
// The subclass must define the Method.  It may optionally define isSync for
// synchronous methods.
//
// Example:
// template <>
// class MyDispatcher<0>
//    : public MethodDispatcher<MyDispatcher, 0,
//        decltype(&MyClass::MyMethod), MyClass::MyMethod> {};
//
// The method may then be called from the source and run on the sink.
//
// Example:
// int result = Run<MyClass::MyMethod>(param1, std::move(param2));

template <template <size_t> typename Derived>
class EmptyMethodDispatcher {
 public:
  template <typename ObjectT>
  static constexpr fn_t<bool, ObjectT&, webgl::RangeConsumerView&>*
  DispatchCommandFuncById(const size_t id) {
    return nullptr;
  }
};

// -

template <typename ReturnT, typename ObjectT, typename... Args>
std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...> ArgsTuple(
    ReturnT (ObjectT::*)(Args... args)) {
  return std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>{};
}

template <typename ReturnT, typename ObjectT, typename... Args>
std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...> ArgsTuple(
    ReturnT (ObjectT::*)(Args... args) const) {
  return std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>{};
}

// Derived type must be parameterized by the ID.
template <template <size_t> typename Derived, size_t _Id, typename MethodType,
          MethodType _Method>
class MethodDispatcher {
  static constexpr auto Id = _Id;
  static constexpr auto Method = _Method;
  using DerivedType = Derived<Id>;

 public:
  template <class ObjectT>
  static constexpr fn_t<bool, ObjectT&, webgl::RangeConsumerView&>*
  DispatchCommandFuncById(const size_t targetId) {
    if (targetId != Id)
      return Derived<Id + 1>::template DispatchCommandFuncById<ObjectT>(
          targetId);

    return [](ObjectT& obj, webgl::RangeConsumerView& view) -> bool {
      const auto viewWas = view;
      (void)viewWas;  // For debugging.

      auto argsTuple = ArgsTuple(Method);
      return std::apply(
          [&](auto&... args) {
            const auto badArgId = webgl::Deserialize(view, 1, args...);
            if (badArgId) {
              const auto& name = DerivedType::Name();
              gfxCriticalError() << "webgl::Deserialize failed for " << name
                                 << " arg " << *badArgId;
              return false;
            }
            (obj.*Method)(args...);
            return true;
          },
          argsTuple);
    };
  }
};

}  // namespace mozilla

#endif  // WEBGLCOMMANDQUEUE_H_

Messung V0.5
C=88 H=99 G=93

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge