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 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 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 74 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 85 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