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/Scissor.h"
17 
18 #include "Rect.h"
19 
20 #include <utils/Log.h>
21 
22 namespace android {
23 namespace uirenderer {
24 
Scissor()25 Scissor::Scissor()
26         : mEnabled(false), mScissorX(0), mScissorY(0), mScissorWidth(0), mScissorHeight(0) {}
27 
setEnabled(bool enabled)28 bool Scissor::setEnabled(bool enabled) {
29     if (mEnabled != enabled) {
30         if (enabled) {
31             glEnable(GL_SCISSOR_TEST);
32         } else {
33             glDisable(GL_SCISSOR_TEST);
34         }
35         mEnabled = enabled;
36         return true;
37     }
38     return false;
39 }
40 
set(GLint x,GLint y,GLint width,GLint height)41 bool Scissor::set(GLint x, GLint y, GLint width, GLint height) {
42     if (mEnabled &&
43         (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight)) {
44         if (x < 0) {
45             width += x;
46             x = 0;
47         }
48         if (y < 0) {
49             height += y;
50             y = 0;
51         }
52         if (width < 0) {
53             width = 0;
54         }
55         if (height < 0) {
56             height = 0;
57         }
58         glScissor(x, y, width, height);
59 
60         mScissorX = x;
61         mScissorY = y;
62         mScissorWidth = width;
63         mScissorHeight = height;
64 
65         return true;
66     }
67     return false;
68 }
69 
set(int viewportHeight,const Rect & clip)70 void Scissor::set(int viewportHeight, const Rect& clip) {
71     // transform to Y-flipped GL space, and prevent negatives
72     GLint x = std::max(0, (int)clip.left);
73     GLint y = std::max(0, viewportHeight - (int)clip.bottom);
74     GLint width = std::max(0, ((int)clip.right) - x);
75     GLint height = std::max(0, (viewportHeight - (int)clip.top) - y);
76 
77     if (x != mScissorX || y != mScissorY || width != mScissorWidth || height != mScissorHeight) {
78         glScissor(x, y, width, height);
79 
80         mScissorX = x;
81         mScissorY = y;
82         mScissorWidth = width;
83         mScissorHeight = height;
84     }
85 }
86 
reset()87 void Scissor::reset() {
88     mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0;
89 }
90 
invalidate()91 void Scissor::invalidate() {
92     mEnabled = glIsEnabled(GL_SCISSOR_TEST);
93     setEnabled(true);
94     reset();
95 }
96 
dump()97 void Scissor::dump() {
98     ALOGD("Scissor: enabled %d, %d %d %d %d", mEnabled, mScissorX, mScissorY, mScissorWidth,
99           mScissorHeight);
100 }
101 
102 } /* namespace uirenderer */
103 } /* namespace android */
104