1
2 /*
3 * Copyright 2016 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "SkColorSpaceXformer.h"
10 #include "SkLights.h"
11 #include "SkReadBuffer.h"
12
MakeFromBuffer(SkReadBuffer & buf)13 sk_sp<SkLights> SkLights::MakeFromBuffer(SkReadBuffer& buf) {
14 Builder builder;
15
16 SkColor3f ambColor;
17 if (!buf.readScalarArray(&ambColor.fX, 3)) {
18 return nullptr;
19 }
20
21 builder.setAmbientLightColor(ambColor);
22
23 int numLights = buf.readInt();
24
25 for (int l = 0; l < numLights; ++l) {
26 bool isPoint = buf.readBool();
27
28 SkColor3f color;
29 if (!buf.readScalarArray(&color.fX, 3)) {
30 return nullptr;
31 }
32
33 SkVector3 dirOrPos;
34 if (!buf.readScalarArray(&dirOrPos.fX, 3)) {
35 return nullptr;
36 }
37
38 sk_sp<SkImage> depthMap;
39 bool hasShadowMap = buf.readBool();
40 if (hasShadowMap) {
41 if (!(depthMap = buf.readImage())) {
42 return nullptr;
43 }
44 }
45
46 bool isRadial = buf.readBool();
47 if (isPoint) {
48 SkScalar intensity;
49 intensity = buf.readScalar();
50 Light light = Light::MakePoint(color, dirOrPos, intensity, isRadial);
51 light.setShadowMap(depthMap);
52 builder.add(light);
53 } else {
54 Light light = Light::MakeDirectional(color, dirOrPos, isRadial);
55 light.setShadowMap(depthMap);
56 builder.add(light);
57 }
58 }
59
60 return builder.finish();
61 }
62
xform_color(const SkColor3f & color,SkColorSpaceXformer * xformer)63 static SkColor3f xform_color(const SkColor3f& color, SkColorSpaceXformer* xformer) {
64 SkColor origColor = SkColorSetARGBInline(0xFF,
65 SkScalarRoundToInt(color.fX),
66 SkScalarRoundToInt(color.fY),
67 SkScalarRoundToInt(color.fZ));
68 SkColor xformedColor = xformer->apply(origColor);
69 return SkColor3f::Make(SkIntToScalar(SkGetPackedR32(xformedColor)),
70 SkIntToScalar(SkGetPackedG32(xformedColor)),
71 SkIntToScalar(SkGetPackedB32(xformedColor)));
72 }
73
makeColorSpace(SkColorSpaceXformer * xformer) const74 sk_sp<SkLights> SkLights::makeColorSpace(SkColorSpaceXformer* xformer) const {
75 SkLights::Builder builder;
76 for (int i = 0; i < this->numLights(); i++) {
77 Light light(fLights[i].type(), xform_color(fLights[i].color(), xformer),
78 fLights[i].fDirOrPos, fLights[i].fIntensity, fLights[i].isRadial());
79 builder.add(light);
80 }
81 builder.setAmbientLightColor(xform_color(fAmbientLightColor, xformer));
82 return builder.finish();
83 }
84
flatten(SkWriteBuffer & buf) const85 void SkLights::flatten(SkWriteBuffer& buf) const {
86 buf.writeScalarArray(&this->ambientLightColor().fX, 3);
87
88 buf.writeInt(this->numLights());
89 for (int l = 0; l < this->numLights(); ++l) {
90 const Light& light = this->light(l);
91
92 bool isPoint = Light::kPoint_LightType == light.type();
93
94 buf.writeBool(isPoint);
95 buf.writeScalarArray(&light.color().fX, 3);
96 buf.writeScalarArray(&light.dir().fX, 3);
97
98 bool hasShadowMap = light.getShadowMap() != nullptr;
99 buf.writeBool(hasShadowMap);
100
101 bool isRadial = light.isRadial();
102 buf.writeBool(isRadial);
103
104 if (hasShadowMap) {
105 buf.writeImage(light.getShadowMap());
106 }
107 if (isPoint) {
108 buf.writeScalar(light.intensity());
109 }
110 }
111 }
112