Home | History | Annotate | Download | only in renderstate
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include <renderstate/Blend.h>
     17 #include "Program.h"
     18 
     19 #include "ShadowTessellator.h"
     20 
     21 namespace android {
     22 namespace uirenderer {
     23 
     24 /**
     25  * Structure mapping Skia xfermodes to OpenGL blending factors.
     26  */
     27 struct Blender {
     28     SkXfermode::Mode mode;
     29     GLenum src;
     30     GLenum dst;
     31 };
     32 
     33 // assumptions made by lookup tables in either this file or ProgramCache
     34 static_assert(0 == SkXfermode::kClear_Mode, "SkXfermode enums have changed");
     35 static_assert(1 == SkXfermode::kSrc_Mode, "SkXfermode enums have changed");
     36 static_assert(2 == SkXfermode::kDst_Mode, "SkXfermode enums have changed");
     37 static_assert(3 == SkXfermode::kSrcOver_Mode, "SkXfermode enums have changed");
     38 static_assert(4 == SkXfermode::kDstOver_Mode, "SkXfermode enums have changed");
     39 static_assert(5 == SkXfermode::kSrcIn_Mode, "SkXfermode enums have changed");
     40 static_assert(6 == SkXfermode::kDstIn_Mode, "SkXfermode enums have changed");
     41 static_assert(7 == SkXfermode::kSrcOut_Mode, "SkXfermode enums have changed");
     42 static_assert(8 == SkXfermode::kDstOut_Mode, "SkXfermode enums have changed");
     43 static_assert(9 == SkXfermode::kSrcATop_Mode, "SkXfermode enums have changed");
     44 static_assert(10 == SkXfermode::kDstATop_Mode, "SkXfermode enums have changed");
     45 static_assert(11 == SkXfermode::kXor_Mode, "SkXfermode enums have changed");
     46 static_assert(12 == SkXfermode::kPlus_Mode, "SkXfermode enums have changed");
     47 static_assert(13 == SkXfermode::kModulate_Mode, "SkXfermode enums have changed");
     48 static_assert(14 == SkXfermode::kScreen_Mode, "SkXfermode enums have changed");
     49 static_assert(15 == SkXfermode::kOverlay_Mode, "SkXfermode enums have changed");
     50 static_assert(16 == SkXfermode::kDarken_Mode, "SkXfermode enums have changed");
     51 static_assert(17 == SkXfermode::kLighten_Mode, "SkXfermode enums have changed");
     52 
     53 // In this array, the index of each Blender equals the value of the first
     54 // entry. For instance, gBlends[1] == gBlends[SkXfermode::kSrc_Mode]
     55 const Blender kBlends[] = {
     56     { SkXfermode::kClear_Mode,    GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA },
     57     { SkXfermode::kSrc_Mode,      GL_ONE,                 GL_ZERO },
     58     { SkXfermode::kDst_Mode,      GL_ZERO,                GL_ONE },
     59     { SkXfermode::kSrcOver_Mode,  GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA },
     60     { SkXfermode::kDstOver_Mode,  GL_ONE_MINUS_DST_ALPHA, GL_ONE },
     61     { SkXfermode::kSrcIn_Mode,    GL_DST_ALPHA,           GL_ZERO },
     62     { SkXfermode::kDstIn_Mode,    GL_ZERO,                GL_SRC_ALPHA },
     63     { SkXfermode::kSrcOut_Mode,   GL_ONE_MINUS_DST_ALPHA, GL_ZERO },
     64     { SkXfermode::kDstOut_Mode,   GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA },
     65     { SkXfermode::kSrcATop_Mode,  GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA },
     66     { SkXfermode::kDstATop_Mode,  GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA },
     67     { SkXfermode::kXor_Mode,      GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
     68     { SkXfermode::kPlus_Mode,     GL_ONE,                 GL_ONE },
     69     { SkXfermode::kModulate_Mode, GL_ZERO,                GL_SRC_COLOR },
     70     { SkXfermode::kScreen_Mode,   GL_ONE,                 GL_ONE_MINUS_SRC_COLOR }
     71 };
     72 
     73 // This array contains the swapped version of each SkXfermode. For instance
     74 // this array's SrcOver blending mode is actually DstOver. You can refer to
     75 // createLayer() for more information on the purpose of this array.
     76 const Blender kBlendsSwap[] = {
     77     { SkXfermode::kClear_Mode,    GL_ONE_MINUS_DST_ALPHA, GL_ZERO },
     78     { SkXfermode::kSrc_Mode,      GL_ZERO,                GL_ONE },
     79     { SkXfermode::kDst_Mode,      GL_ONE,                 GL_ZERO },
     80     { SkXfermode::kSrcOver_Mode,  GL_ONE_MINUS_DST_ALPHA, GL_ONE },
     81     { SkXfermode::kDstOver_Mode,  GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA },
     82     { SkXfermode::kSrcIn_Mode,    GL_ZERO,                GL_SRC_ALPHA },
     83     { SkXfermode::kDstIn_Mode,    GL_DST_ALPHA,           GL_ZERO },
     84     { SkXfermode::kSrcOut_Mode,   GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA },
     85     { SkXfermode::kDstOut_Mode,   GL_ONE_MINUS_DST_ALPHA, GL_ZERO },
     86     { SkXfermode::kSrcATop_Mode,  GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA },
     87     { SkXfermode::kDstATop_Mode,  GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA },
     88     { SkXfermode::kXor_Mode,      GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
     89     { SkXfermode::kPlus_Mode,     GL_ONE,                 GL_ONE },
     90     { SkXfermode::kModulate_Mode, GL_DST_COLOR,           GL_ZERO },
     91     { SkXfermode::kScreen_Mode,   GL_ONE_MINUS_DST_COLOR, GL_ONE }
     92 };
     93 
     94 Blend::Blend()
     95     : mEnabled(false)
     96     , mSrcMode(GL_ZERO)
     97     , mDstMode(GL_ZERO) {
     98     // gl blending off by default
     99 }
    100 
    101 void Blend::invalidate() {
    102     syncEnabled();
    103     mSrcMode = mDstMode = GL_ZERO;
    104 }
    105 
    106 void Blend::syncEnabled() {
    107     if (mEnabled) {
    108         glEnable(GL_BLEND);
    109     } else {
    110         glDisable(GL_BLEND);
    111     }
    112 }
    113 
    114 void Blend::getFactors(SkXfermode::Mode mode, ModeOrderSwap modeUsage, GLenum* outSrc, GLenum* outDst) {
    115     *outSrc = (modeUsage == ModeOrderSwap::Swap) ? kBlendsSwap[mode].src : kBlends[mode].src;
    116     *outDst = (modeUsage == ModeOrderSwap::Swap) ? kBlendsSwap[mode].dst : kBlends[mode].dst;
    117 }
    118 
    119 void Blend::setFactors(GLenum srcMode, GLenum dstMode) {
    120     if (srcMode == GL_ZERO && dstMode == GL_ZERO) {
    121         // disable blending
    122         if (mEnabled) {
    123             glDisable(GL_BLEND);
    124             mEnabled = false;
    125         }
    126     } else {
    127         // enable blending
    128         if (!mEnabled) {
    129             glEnable(GL_BLEND);
    130             mEnabled = true;
    131         }
    132 
    133         if (srcMode != mSrcMode || dstMode != mDstMode) {
    134             glBlendFunc(srcMode, dstMode);
    135             mSrcMode = srcMode;
    136             mDstMode = dstMode;
    137         }
    138     }
    139 }
    140 
    141 void Blend::dump() {
    142     ALOGD("Blend: enabled %d, func src %d, dst %d", mEnabled, mSrcMode, mDstMode);
    143 }
    144 
    145 } /* namespace uirenderer */
    146 } /* namespace android */
    147 
    148