author Xianzhu Wang <>
Tue, 05 Mar 2019 12:18:01 +0000
changeset 464575 4325ba7b38576495a78289c2a8f4dff391922e66
parent 452446 f0a91d36587266d7454a450c6044d573664fbed5
child 465495 e02bd4f991578e9e6529bf0b63f2a1115a3942a4
permissions -rw-r--r--
Bug 1529059 [wpt PR 15420] - [BlinkGenPropertyTrees] Initiailize double_sided of synthetic effect, a=testonly Automatic update from web-platform-tests [BlinkGenPropertyTrees] Initiailize double_sided of synthetic effect Previously synthetic effects always had double_sided==false, causing the layer disappear when the backface was facing forward. Bug: 928190 Change-Id: I35534b40346d5c5918bc99c00a4ca6b4e3b68796 Reviewed-on: Reviewed-by: Philip Rogers <> Commit-Queue: Xianzhu Wang <> Cr-Commit-Position: refs/heads/master@{#632764} -- wpt-commits: a89467050deaf1dcbd9140a2f0670b1b85e518ee wpt-pr: 15420

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 */

/* C++ types corresponding to Servo and Gecko types used across bindings,
   with some annotations to indicate ownership expectations */

// This file defines a number of C++ types used to represent borrowed,
// strong, and owning references to Servo and Gecko objects that might
// be used across bindings and FFI.
// By convention, the types defined here are named "RawServo{Type}" and
// "RawGecko{Type}".  The {Type} should be something close to the real Rust or
// C++ name of the type, but need not be.  The "Raw" is really just used to
// avoid clashing with other names.
// For Servo types, each "RawServo{ServoTypeName}" is generated as an opaque,
// declared but not defined struct.
// For Gecko types, each "RawGecko{GeckoTypeName}" is a typedef that aliases
// the actual C++ type.
// Each of these types can have a number of different typedefs generated for
// them, representing different notions of ownership when passing or receiving
// these values across bindings and FFI:
//   Raw{Gecko,Servo}{Type}Borrowed
//   Raw{Gecko,Servo}{Type}BorrowedOrNull
//     immutable, borrowed reference (or null)
//   Raw{Gecko,Servo}{Type}BorrowedMut
//   Raw{Gecko,Servo}{Type}BorrowedMutOrNull
//     mutable, borrowed reference (or null)
//   RawServo{Type}Strong
//     strong reference to an Arc-managed value
//   RawServo{Type}Owned
//   RawServo{Type}OwnedOrNull
//     owned reference to a Box-managed value (or null)
// All of these borrowed, strong, and owned types are generated by adding
// entries to one of these files:
//   BorrowedTypeList.h
//     generates some or all of the Borrowed types
//   ServoArcTypeList.h
//     generates all of the Borrowed types and the Strong type
//   ServoBoxedTypeList.h
//     generates all of the Borrowed types and the Owned & OwnedNull types
// The borrowed, strong, and owned reference types should be used in FFI
// function signatures where possible, to help indicate the ownership properties
// that both sides of the function call must adhere to.
// There are some special cases defined at the bottom of this file that don't
// fit neatly into these three categories.
// Using these types in C++
// ========================
// All of the Borrowed types are C++ typedefs for raw pointers, and can be used
// directly.  Since the types they point to are opaque, there isn't much that
// can be done with these apart from passing them around, holding on to them,
// checking them for equality, etc.  If they are Arc-managed or Box-managed
// Servo types, they can be assigned to a RefPtr<> or UniquePtr<>.
// The Strong types are a C++ struct that wraps a raw pointer.  When receiving
// a Strong value from a Servo_* FFI function, you must call Consume() on it
// to convert it into an already_AddRefed<RawServo{Type}>, otherwise it will
// leak.
// We don't currently have any cases where we pass a Strong value to Servo; this
// could be done by creating a RawServo{Type}Strong struct value whose mPtr is
// initialized to the result of calling `.forget().take()` on a
// RefPtr<RawServo{Type}>, but it's probably easier just to pass a Borrowed
// value and let the Rust code turn it into an Arc.
// The Owned types are C++ typedefs for raw pointers.  When receiving an Owned
// value from a Servo_* FFI function, it should be assigned to a UniquePtr<>,
// otherwise it will leak.
// To pass an Owned value to Servo, call `release()` on the UniquePtr<> it's
// living in (to take ownership of it), and pass that pointer in directly.
// TODO(heycam): We should perhaps have a similar struct for Owned types with
// a Consume() method to convert them into a UniquePtr.  The struct for Strong
// types at least have MOZ_MUST_USE_TYPE on them.
// Using these types in Rust
// =========================
// The FFI type names are available in Rust in the gecko_bindings::bindings mod,
// which is generated by servo/components/style/
// The Borrowed types are defined as Rust reference types.
// Borrowed types for Gecko values are references to the bindgened versions of
// the C++ types, so when receiving references over FFI into a Servo_* function,
// they can be used directly, and when returning them back to Gecko, the
// reference can be returned directly.
// Borrowed types for Servo values are references to an opaque type, which must
// be converted to or from the appropriate Rust type:
//   For an Arc-owned value, a RawServoFooBorrowed received from FFI can be
//   converted into a `&Arc<Foo>` by calling `Foo::as_arc(&raw_servo_foo)`.
//   Returning a RawServoFooBorrowed over FFI back to Gecko can be done by
//   calling `as_borrowed()` on the `Arc<Foo>`.
//   For a Box-owned value, a RawServoFooBorrowed received from FFI can be
//   converted into a `&Foo` by calling `Foo::from_ffi(&raw_servo_foo)`.
//   Returning a RawServoFooBorrowed over FFI back to Gecko can be done by
//   calling `as_ffi()` on the `Foo`.
// The Strong types are defined as gecko_bindings::sugar::ownership::Strong<T>.
// This is an FFI safe type that represents the value with a strong reference
// already added to it.  Dropping a Strong<T> will leak the strong reference.
// A RawServoFooStrong received from FFI can be converted into a
// `RawOffsetArc<Foo>` by calling `into_arc()` or `into_arc_opt()` on it.
// To pass a RawServoFooStrong back to Gecko, call `into_strong()` on the
// `Arc<Foo>`.
// The Owned types are defined as gecko_bindings::sugar::ownership::Owned<T>
// (or OwnedOrNull<T>).
// This is another FFI safe type that represents the owning reference to the
// value.  Dropping an Owned<T> will leak the value.
// A RawServoFooOwned received from FFI can be converted into a `Box<Foo>`
// by calling `into_box()` or `into_box_opt()` on it.  To pass a
// RawServoFooOwned back to Gecko, call `HasBoxFFI::into_ffi()` passing in
// the `Box<Foo>` value.
// Reading through servo/components/style/gecko_bindings/sugar/
// is also instructive in understanding all this.

#ifndef mozilla_ServoBindingTypes_h
#define mozilla_ServoBindingTypes_h

#include "mozilla/RefPtr.h"
#include "mozilla/ServoComputedData.h"
#include "mozilla/ServoTypes.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/gfx/Types.h"
#include "nsCSSPropertyID.h"
#include "nsStyleAutoArray.h"
#include "nsTArray.h"

// Forward declarations.

#define SERVO_BOXED_TYPE(name_, type_) struct type_;
#include "mozilla/ServoBoxedTypeList.h"

#define SERVO_ARC_TYPE(name_, type_) struct type_;
#include "mozilla/ServoArcTypeList.h"

class nsCSSPropertyIDSet;
class nsCSSValue;
class nsINode;
class nsPresContext;
class nsXBLBinding;
struct nsFontFaceRuleContainer;
struct nsTimingFunction;

namespace mozilla {
class ComputedStyle;
class ServoElementSnapshot;
struct AnimationPropertySegment;
struct ComputedTiming;
struct Keyframe;
struct PropertyStyleAnimationValuePair;
struct PropertyValuePair;
struct StyleAnimation;
struct URLExtraData;
using ComputedKeyframeValues = nsTArray<PropertyStyleAnimationValuePair>;
using GfxMatrix4x4 = mozilla::gfx::Float[16];

namespace dom {
class StyleChildrenIterator;
class Document;
class Element;
}  // namespace dom
}  // namespace mozilla

#define DECL_BORROWED_REF_TYPE_FOR(type_) typedef type_ const* type_##Borrowed;
  typedef type_ const* type_##BorrowedOrNull;
#define DECL_BORROWED_MUT_REF_TYPE_FOR(type_) typedef type_* type_##BorrowedMut;
  typedef type_* type_##BorrowedMutOrNull;

#define DECL_OWNED_REF_TYPE_FOR(type_) \
  typedef type_* type_##Owned;         \

  typedef type_* type_##OwnedOrNull;            \

#define GECKO_BORROWED_TYPE(geckotype_, ffitype_) \
  using ffitype_ = geckotype_;                    \
  using ffitype_##Borrowed = const ffitype_*;     \
  using ffitype_##BorrowedOrNull = const ffitype_*;
#define GECKO_BORROWED_TYPE_MUT(geckotype_, ffitype_) \
  GECKO_BORROWED_TYPE(geckotype_, ffitype_)           \
  using ffitype_##BorrowedMut = ffitype_*;            \
  using ffitype_##BorrowedMutOrNull = ffitype_*;
#include "mozilla/BorrowedTypeList.h"

#define SERVO_ARC_TYPE(name_, type_)                                    \
  DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_)                            \
  DECL_BORROWED_REF_TYPE_FOR(type_)                                     \
  DECL_BORROWED_MUT_REF_TYPE_FOR(type_)                                 \
  struct MOZ_MUST_USE_TYPE type_##Strong {                              \
    type_* mPtr;                                                        \
    already_AddRefed<type_> Consume();                                  \
  };                                                                    \
  extern "C" {                                                          \
  void Servo_##name_##_AddRef(type_##Borrowed ptr);                     \
  void Servo_##name_##_Release(type_##Borrowed ptr);                    \
  }                                                                     \
  namespace mozilla {                                                   \
  template <>                                                           \
  struct RefPtrTraits<type_> {                                          \
    static void AddRef(type_* aPtr) { Servo_##name_##_AddRef(aPtr); }   \
    static void Release(type_* aPtr) { Servo_##name_##_Release(aPtr); } \
  };                                                                    \
#include "mozilla/ServoArcTypeList.h"

#define SERVO_BOXED_TYPE(name_, type_)                                 \
  DECL_OWNED_REF_TYPE_FOR(type_)                                       \
  DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_)                              \
  extern "C" void Servo_##name_##_Drop(type_##Owned ptr);              \
  namespace mozilla {                                                  \
  template <>                                                          \
  class DefaultDelete<type_> {                                         \
   public:                                                             \
    void operator()(type_* aPtr) const { Servo_##name_##_Drop(aPtr); } \
  };                                                                   \
#include "mozilla/ServoBoxedTypeList.h"

#define DEFINE_ARRAY_TYPE_FOR(type_)                               \
  struct nsTArrayBorrowed_##type_ {                                \
    nsTArray<type_>* mArray;                                       \
    MOZ_IMPLICIT nsTArrayBorrowed_##type_(nsTArray<type_>* aArray) \
        : mArray(aArray) {}                                        \

// Other special cases.

typedef void* RawServoAnimationValueTableBorrowed;

// TODO(heycam): Handle these elsewhere.
struct RawServoAnimationValueMap;

typedef mozilla::ComputedStyle const* ComputedStyleBorrowed;
typedef mozilla::ComputedStyle const* ComputedStyleBorrowedOrNull;
typedef ServoComputedData const* ServoComputedDataBorrowed;

struct MOZ_MUST_USE_TYPE ComputedStyleStrong {
  mozilla::ComputedStyle* mPtr;
  already_AddRefed<mozilla::ComputedStyle> Consume();

// This is a reference to a reference of RawServoDeclarationBlock, which
// corresponds to Option<&Arc<Locked<RawServoDeclarationBlock>>> in Servo side.


#endif  // mozilla_ServoBindingTypes_h