forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathzcr_alpha_compositing.cc
141 lines (115 loc) · 4.56 KB
/
zcr_alpha_compositing.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/exo/wayland/zcr_alpha_compositing.h"
#include <alpha-compositing-unstable-v1-server-protocol.h>
#include "components/exo/surface.h"
#include "components/exo/surface_observer.h"
#include "components/exo/wayland/server_util.h"
namespace exo {
namespace wayland {
namespace {
// A property key containing a boolean set to true if a blending object is
// associated with surface object.
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasBlendingKey, false)
////////////////////////////////////////////////////////////////////////////////
// blending_interface:
// Implements the blending interface to a Surface. The "blend mode" and
// "alpha"-state is set to SrcOver and 1 upon destruction. A window property
// will be set during the lifetime of this class to prevent multiple instances
// from being created for the same Surface.
class Blending : public SurfaceObserver {
public:
explicit Blending(Surface* surface) : surface_(surface) {
surface_->AddSurfaceObserver(this);
surface_->SetProperty(kSurfaceHasBlendingKey, true);
}
~Blending() override {
if (surface_) {
surface_->RemoveSurfaceObserver(this);
surface_->SetBlendMode(SkBlendMode::kSrcOver);
surface_->SetAlpha(1.0f);
surface_->SetProperty(kSurfaceHasBlendingKey, false);
}
}
void SetBlendMode(SkBlendMode blend_mode) {
if (surface_)
surface_->SetBlendMode(blend_mode);
}
void SetAlpha(float value) {
if (surface_)
surface_->SetAlpha(value);
}
// Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override {
surface->RemoveSurfaceObserver(this);
surface_ = nullptr;
}
private:
Surface* surface_;
DISALLOW_COPY_AND_ASSIGN(Blending);
};
void blending_destroy(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
void blending_set_blending(wl_client* client,
wl_resource* resource,
uint32_t equation) {
switch (equation) {
case ZCR_BLENDING_V1_BLENDING_EQUATION_NONE:
GetUserDataAs<Blending>(resource)->SetBlendMode(SkBlendMode::kSrc);
break;
case ZCR_BLENDING_V1_BLENDING_EQUATION_PREMULT:
GetUserDataAs<Blending>(resource)->SetBlendMode(SkBlendMode::kSrcOver);
break;
case ZCR_BLENDING_V1_BLENDING_EQUATION_COVERAGE:
NOTIMPLEMENTED();
break;
default:
DLOG(WARNING) << "Unsupported blending equation: " << equation;
break;
}
}
void blending_set_alpha(wl_client* client,
wl_resource* resource,
wl_fixed_t alpha) {
GetUserDataAs<Blending>(resource)->SetAlpha(wl_fixed_to_double(alpha));
}
const struct zcr_blending_v1_interface blending_implementation = {
blending_destroy, blending_set_blending, blending_set_alpha};
////////////////////////////////////////////////////////////////////////////////
// alpha_compositing_interface:
void alpha_compositing_destroy(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
void alpha_compositing_get_blending(wl_client* client,
wl_resource* resource,
uint32_t id,
wl_resource* surface_resource) {
Surface* surface = GetUserDataAs<Surface>(surface_resource);
if (surface->GetProperty(kSurfaceHasBlendingKey)) {
wl_resource_post_error(resource,
ZCR_ALPHA_COMPOSITING_V1_ERROR_BLENDING_EXISTS,
"a blending object for that surface already exists");
return;
}
wl_resource* blending_resource =
wl_resource_create(client, &zcr_blending_v1_interface, 1, id);
SetImplementation(blending_resource, &blending_implementation,
std::make_unique<Blending>(surface));
}
const struct zcr_alpha_compositing_v1_interface
alpha_compositing_implementation = {alpha_compositing_destroy,
alpha_compositing_get_blending};
} // namespace
void bind_alpha_compositing(wl_client* client,
void* data,
uint32_t version,
uint32_t id) {
wl_resource* resource =
wl_resource_create(client, &zcr_alpha_compositing_v1_interface, 1, id);
wl_resource_set_implementation(resource, &alpha_compositing_implementation,
data, nullptr);
}
} // namespace wayland
} // namespace exo