1 /*
2     Copyright (c) 2005-2021 Intel Corporation
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 
17 // rpolygon.h
18 //
19 #ifndef TBB_examples_polygon_overlay_rpolygon_H
20 #define TBB_examples_polygon_overlay_rpolygon_H
21 
22 #include <vector>
23 #include <iostream>
24 
25 #include "oneapi/tbb/scalable_allocator.h"
26 #include "oneapi/tbb/concurrent_vector.h"
27 #include "oneapi/tbb/enumerable_thread_specific.h"
28 
29 #include "pover_video.hpp"
30 
31 class RPolygon;
32 typedef oneapi::tbb::scalable_allocator<RPolygon> RPolygon_allocator;
33 DEFINE RPolygon_allocator rAlloc;
34 
35 enum MallocBehavior { UseMalloc, UseScalableAllocator };
36 
37 DEFINE MallocBehavior gMBehavior INIT(UseScalableAllocator);
38 
39 class RPolygon {
40 public:
RPolygon()41     RPolygon() {
42         m_XMin = m_YMin = m_XMax = m_YMax = 0;
43         m_r = m_g = m_b = 0;
44     }
RPolygon(int xMin,int yMin,int xMax,int yMax,int r=-1,int g=-1,int b=-1)45     RPolygon(int xMin, int yMin, int xMax, int yMax, int r = -1, int g = -1, int b = -1)
46             : m_XMin(xMin),
47               m_YMin(yMin),
48               m_XMax(xMax),
49               m_YMax(yMax) {
50         if (r >= 0) {
51             m_r = (colorcomp_t)r;
52             m_g = (colorcomp_t)g;
53             m_b = (colorcomp_t)b;
54             if (gDoDraw)
55                 drawPoly();
56         }
57     }
58 
set_nodraw(int xMin,int yMin,int xMax,int yMax)59     void set_nodraw(int xMin, int yMin, int xMax, int yMax) {
60         m_XMin = xMin;
61         m_YMin = yMin;
62         m_XMax = xMax;
63         m_YMax = yMax;
64     }
65 
66     RPolygon &intersect(RPolygon &otherPoly);
set(int xMin,int yMin,int xMax,int yMax)67     void set(int xMin, int yMin, int xMax, int yMax) {
68         set_nodraw(xMin, yMin, xMax, yMax);
69         if (gDoDraw) {
70             drawPoly();
71         }
72     }
get(int * xMin,int * yMin,int * xMax,int * yMax) const73     void get(int *xMin, int *yMin, int *xMax, int *yMax) const {
74         *xMin = m_XMin;
75         *yMin = m_YMin;
76         *xMax = m_XMax;
77         *yMax = m_YMax;
78     }
xmax() const79     int xmax() const {
80         return m_XMax;
81     }
xmin() const82     int xmin() const {
83         return m_XMin;
84     }
ymax() const85     int ymax() const {
86         return m_YMax;
87     }
ymin() const88     int ymin() const {
89         return m_YMin;
90     }
setColor(colorcomp_t newr,colorcomp_t newg,colorcomp_t newb)91     void setColor(colorcomp_t newr, colorcomp_t newg, colorcomp_t newb) {
92         m_r = newr;
93         m_g = newg;
94         m_b = newb;
95     }
getColor(int * myr,int * myg,int * myb)96     void getColor(int *myr, int *myg, int *myb) {
97         *myr = m_r;
98         *myg = m_g;
99         *myb = m_b;
100     }
myColor()101     color_t myColor() {
102         return gVideo->get_color(m_r, m_g, m_b);
103     }
drawPoly()104     void drawPoly() {
105         if (gVideo->running) {
106             if (g_next_frame()) { // Shouldn't call next_frame each time
107                 drawing_area ldrawing(gDrawXOffset + m_XMin * gPolyXBoxSize, //x
108                                       gDrawYOffset + m_YMin * gPolyYBoxSize, //y
109                                       (m_XMax - m_XMin + 1) * gPolyXBoxSize, //sizex
110                                       (m_YMax - m_YMin + 1) * gPolyYBoxSize); //sizey
111                 for (int y = 0; y < ldrawing.size_y; y++) {
112                     ldrawing.set_pos(0, y);
113                     color_t my_color = myColor();
114                     for (int x = 0; x < ldrawing.size_x; x++) {
115                         ldrawing.put_pixel(my_color);
116                     }
117                 }
118             }
119         }
120     }
121 
area()122     int area() {
123         return ((m_XMax - m_XMin + 1) * (m_YMax - m_YMin + 1));
124     }
print(int i)125     void print(int i) {
126         std::cout << "RPolygon " << i << " (" << m_XMin << ", " << m_YMin << ")-(" << m_XMax << ", "
127                   << m_YMax << ") "
128                   << "\n";
129         fflush(stdout);
130     }
131 
132 private:
133     int m_XMin;
134     int m_YMin;
135     int m_XMax;
136     int m_YMax;
137     colorcomp_t m_r;
138     colorcomp_t m_g;
139     colorcomp_t m_b;
140 };
141 
142 #if _MAIN_C_
operator <(const RPolygon & a,const RPolygon & b)143 bool operator<(const RPolygon &a, const RPolygon &b) {
144     if (a.ymin() > b.ymin())
145         return false;
146     if (a.ymin() < b.ymin())
147         return true;
148     return a.xmin() < b.xmin();
149 }
150 #else
151 extern bool operator<(const RPolygon &a, const RPolygon &b);
152 #endif
153 
154 extern std::ostream &operator<<(std::ostream &s, const RPolygon &p);
155 
156 class RPolygon_flagged {
157     RPolygon *myPoly;
158     bool is_duplicate;
159 
160 public:
RPolygon_flagged()161     RPolygon_flagged() {
162         myPoly = nullptr;
163         is_duplicate = false;
164     }
RPolygon_flagged(RPolygon * _p,bool _is_duplicate)165     RPolygon_flagged(RPolygon *_p, bool _is_duplicate) : myPoly(_p), is_duplicate(_is_duplicate) {}
isDuplicate()166     bool isDuplicate() {
167         return is_duplicate;
168     }
setDuplicate(bool newValue)169     void setDuplicate(bool newValue) {
170         is_duplicate = newValue;
171     }
p()172     RPolygon *p() {
173         return myPoly;
174     }
setp(RPolygon * newp)175     void setp(RPolygon *newp) {
176         myPoly = newp;
177     }
178 };
179 
180 typedef class std::vector<RPolygon, RPolygon_allocator> Polygon_map_t;
181 typedef class oneapi::tbb::concurrent_vector<RPolygon, RPolygon_allocator> concurrent_Polygon_map_t;
182 typedef class oneapi::tbb::enumerable_thread_specific<Polygon_map_t> ETS_Polygon_map_t;
183 typedef class std::vector<RPolygon_flagged, oneapi::tbb::tbb_allocator<RPolygon_flagged>>
184     Flagged_map_t; // we'll make shallow copies
185 
PolygonsOverlap(RPolygon * p1,RPolygon * p2,int & xl,int & yl,int & xh,int & yh)186 inline bool PolygonsOverlap(RPolygon *p1, RPolygon *p2, int &xl, int &yl, int &xh, int &yh) {
187     int xl1, yl1, xh1, yh1, xl2, yl2, xh2, yh2;
188 #if _DEBUG
189     rt_sleep(1); // slow down the process so we can see it.
190 #endif
191     p1->get(&xl1, &yl1, &xh1, &yh1);
192     p2->get(&xl2, &yl2, &xh2, &yh2);
193     if (xl1 > xh2)
194         return false;
195     if (xh1 < xl2)
196         return false;
197     if (yl1 > yh2)
198         return false;
199     if (yh1 < yl2)
200         return false;
201     xl = (xl1 < xl2) ? xl2 : xl1;
202     xh = (xh1 < xh2) ? xh1 : xh2;
203     yl = (yl1 < yl2) ? yl2 : yl1;
204     yh = (yh1 < yh2) ? yh1 : yh2;
205     return true;
206 }
207 
208 #endif // TBB_examples_polygon_overlay_rpolygon_H
209