Home | History | Annotate | Download | only in core
      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