1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "FrameBuffer.hpp" 16 17 #include "Device/Surface.hpp" 18 #include "Reactor/Reactor.hpp" 19 #include "System/Timer.hpp" 20 #include "System/Debug.hpp" 21 22 #include <stdio.h> 23 #include <string.h> 24 #include <time.h> 25 26 #define ASYNCHRONOUS_BLIT false // FIXME: Currently leads to rare race conditions 27 28 namespace sw 29 { 30 extern bool forceWindowed; 31 32 FrameBuffer::Cursor FrameBuffer::cursor = {}; 33 bool FrameBuffer::topLeftOrigin = false; 34 35 FrameBuffer::FrameBuffer(int width, int height, bool fullscreen, bool topLeftOrigin) 36 { 37 this->topLeftOrigin = topLeftOrigin; 38 39 framebuffer = nullptr; 40 41 this->width = width; 42 this->height = height; 43 format = VK_FORMAT_B8G8R8A8_UNORM; 44 stride = 0; 45 46 windowed = !fullscreen || forceWindowed; 47 48 blitFunction = nullptr; 49 blitRoutine = nullptr; 50 blitState = {}; 51 52 if(ASYNCHRONOUS_BLIT) 53 { 54 terminate = false; 55 FrameBuffer *parameters = this; 56 blitThread = new Thread(threadFunction, ¶meters); 57 } 58 } 59 60 FrameBuffer::~FrameBuffer() 61 { 62 if(ASYNCHRONOUS_BLIT) 63 { 64 terminate = true; 65 blitEvent.signal(); 66 blitThread->join(); 67 delete blitThread; 68 } 69 70 delete blitRoutine; 71 } 72 73 void FrameBuffer::setCursorImage(sw::Surface *cursorImage) 74 { 75 if(cursorImage) 76 { 77 cursor.image = cursorImage->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); 78 cursorImage->unlockExternal(); 79 80 cursor.width = cursorImage->getWidth(); 81 cursor.height = cursorImage->getHeight(); 82 } 83 else 84 { 85 cursor.width = 0; 86 cursor.height = 0; 87 } 88 } 89 90 void FrameBuffer::setCursorOrigin(int x0, int y0) 91 { 92 cursor.hotspotX = x0; 93 cursor.hotspotY = y0; 94 } 95 96 void FrameBuffer::setCursorPosition(int x, int y) 97 { 98 cursor.positionX = x; 99 cursor.positionY = y; 100 } 101 102 void FrameBuffer::copy(sw::Surface *source) 103 { 104 if(!source) 105 { 106 return; 107 } 108 109 if(!lock()) 110 { 111 return; 112 } 113 114 int sourceStride = source->getInternalPitchB(); 115 116 updateState = {}; 117 updateState.width = width; 118 updateState.height = height; 119 updateState.destFormat = format; 120 updateState.destStride = stride; 121 updateState.sourceFormat = source->getInternalFormat(); 122 updateState.sourceStride = topLeftOrigin ? sourceStride : -sourceStride; 123 updateState.cursorWidth = cursor.width; 124 updateState.cursorHeight = cursor.height; 125 126 renderbuffer = source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); 127 128 if(!topLeftOrigin) 129 { 130 renderbuffer = (byte*)renderbuffer + (height - 1) * sourceStride; 131 } 132 133 cursor.x = cursor.positionX - cursor.hotspotX; 134 cursor.y = cursor.positionY - cursor.hotspotY; 135 136 if(ASYNCHRONOUS_BLIT) 137 { 138 blitEvent.signal(); 139 syncEvent.wait(); 140 } 141 else 142 { 143 copyLocked(); 144 } 145 146 source->unlockInternal(); 147 unlock(); 148 149 profiler.nextFrame(); // Assumes every copy() is a full frame 150 } 151 152 void FrameBuffer::copyLocked() 153 { 154 if(memcmp(&blitState, &updateState, sizeof(BlitState)) != 0) 155 { 156 blitState = updateState; 157 delete blitRoutine; 158 159 blitRoutine = copyRoutine(blitState); 160 blitFunction = (void(*)(void*, void*, Cursor*))blitRoutine->getEntry(); 161 } 162 163 blitFunction(framebuffer, renderbuffer, &cursor); 164 } 165 166 Routine *FrameBuffer::copyRoutine(const BlitState &state) 167 { 168 const int width = state.width; 169 const int height = state.height; 170 const int dBytes = Surface::bytes(state.destFormat); 171 const int dStride = state.destStride; 172 const int sBytes = Surface::bytes(state.sourceFormat); 173 const int sStride = state.sourceStride; 174 175 Function<Void(Pointer<Byte>, Pointer<Byte>, Pointer<Byte>)> function; 176 { 177 Pointer<Byte> dst(function.Arg<0>()); 178 Pointer<Byte> src(function.Arg<1>()); 179 Pointer<Byte> cursor(function.Arg<2>()); 180 181 For(Int y = 0, y < height, y++) 182 { 183 Pointer<Byte> d = dst + y * dStride; 184 Pointer<Byte> s = src + y * sStride; 185 186 Int x0 = 0; 187 188 switch(state.destFormat) 189 { 190 case VK_FORMAT_B8G8R8A8_UNORM: 191 { 192 Int x = x0; 193 194 switch(state.sourceFormat) 195 { 196 case VK_FORMAT_B8G8R8A8_UNORM: 197 For(, x < width - 3, x += 4) 198 { 199 *Pointer<Int4>(d, 1) = *Pointer<Int4>(s, sStride % 16 ? 1 : 16); 200 201 s += 4 * sBytes; 202 d += 4 * dBytes; 203 } 204 break; 205 case VK_FORMAT_R8G8B8A8_UNORM: 206 For(, x < width - 3, x += 4) 207 { 208 Int4 bgra = *Pointer<Int4>(s, sStride % 16 ? 1 : 16); 209 210 *Pointer<Int4>(d, 1) = ((bgra & Int4(0x00FF0000)) >> 16) | 211 ((bgra & Int4(0x000000FF)) << 16) | 212 (bgra & Int4(0xFF00FF00)); 213 214 s += 4 * sBytes; 215 d += 4 * dBytes; 216 } 217 break; 218 case VK_FORMAT_R16G16B16A16_UNORM: 219 For(, x < width - 1, x += 2) 220 { 221 Short4 c0 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8; 222 Short4 c1 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 8), 0xC6)) >> 8; 223 224 *Pointer<Int2>(d) = As<Int2>(PackUnsigned(c0, c1)); 225 226 s += 2 * sBytes; 227 d += 2 * dBytes; 228 } 229 break; 230 case VK_FORMAT_R5G6B5_UNORM_PACK16: 231 For(, x < width - 3, x += 4) 232 { 233 Int4 rgb = Int4(*Pointer<Short4>(s)); 234 235 *Pointer<Int4>(d) = (((rgb & Int4(0xF800)) << 8) | ((rgb & Int4(0xE01F)) << 3)) | 236 (((rgb & Int4(0x07E0)) << 5) | ((rgb & Int4(0x0600)) >> 1)) | 237 (((rgb & Int4(0x001C)) >> 2) | Int4(0xFF000000)); 238 239 s += 4 * sBytes; 240 d += 4 * dBytes; 241 } 242 break; 243 default: 244 ASSERT(false); 245 break; 246 } 247 248 For(, x < width, x++) 249 { 250 switch(state.sourceFormat) 251 { 252 case VK_FORMAT_B8G8R8A8_UNORM: 253 *Pointer<Int>(d) = *Pointer<Int>(s); 254 break; 255 case VK_FORMAT_R8G8B8A8_UNORM: 256 { 257 Int rgba = *Pointer<Int>(s); 258 259 *Pointer<Int>(d) = ((rgba & Int(0x00FF0000)) >> 16) | 260 ((rgba & Int(0x000000FF)) << 16) | 261 (rgba & Int(0xFF00FF00)); 262 } 263 break; 264 case VK_FORMAT_R16G16B16A16_UNORM: 265 { 266 Short4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8; 267 268 *Pointer<Int>(d) = Int(As<Int2>(PackUnsigned(c, c))); 269 } 270 break; 271 case VK_FORMAT_R5G6B5_UNORM_PACK16: 272 { 273 Int rgb = Int(*Pointer<Short>(s)); 274 275 *Pointer<Int>(d) = 0xFF000000 | 276 ((rgb & 0xF800) << 8) | ((rgb & 0xE01F) << 3) | 277 ((rgb & 0x07E0) << 5) | ((rgb & 0x0600) >> 1) | 278 ((rgb & 0x001C) >> 2); 279 } 280 break; 281 default: 282 ASSERT(false); 283 break; 284 } 285 286 s += sBytes; 287 d += dBytes; 288 } 289 } 290 break; 291 case VK_FORMAT_R8G8B8A8_UNORM: 292 case VK_FORMAT_R8G8B8A8_SRGB: 293 { 294 Int x = x0; 295 296 switch(state.sourceFormat) 297 { 298 case VK_FORMAT_R8G8B8A8_UNORM: 299 For(, x < width - 3, x += 4) 300 { 301 *Pointer<Int4>(d, 1) = *Pointer<Int4>(s, sStride % 16 ? 1 : 16); 302 303 s += 4 * sBytes; 304 d += 4 * dBytes; 305 } 306 break; 307 case VK_FORMAT_B8G8R8A8_UNORM: 308 For(, x < width - 3, x += 4) 309 { 310 Int4 bgra = *Pointer<Int4>(s, sStride % 16 ? 1 : 16); 311 312 *Pointer<Int4>(d, 1) = ((bgra & Int4(0x00FF0000)) >> 16) | 313 ((bgra & Int4(0x000000FF)) << 16) | 314 (bgra & Int4(0xFF00FF00)); 315 316 s += 4 * sBytes; 317 d += 4 * dBytes; 318 } 319 break; 320 case VK_FORMAT_R16G16B16A16_UNORM: 321 For(, x < width - 1, x += 2) 322 { 323 Short4 c0 = *Pointer<UShort4>(s + 0) >> 8; 324 Short4 c1 = *Pointer<UShort4>(s + 8) >> 8; 325 326 *Pointer<Int2>(d) = As<Int2>(PackUnsigned(c0, c1)); 327 328 s += 2 * sBytes; 329 d += 2 * dBytes; 330 } 331 break; 332 case VK_FORMAT_R5G6B5_UNORM_PACK16: 333 For(, x < width - 3, x += 4) 334 { 335 Int4 rgb = Int4(*Pointer<Short4>(s)); 336 337 *Pointer<Int4>(d) = Int4(0xFF000000) | 338 (((rgb & Int4(0x001F)) << 19) | ((rgb & Int4(0x001C)) << 14)) | 339 (((rgb & Int4(0x07E0)) << 5) | ((rgb & Int4(0x0600)) >> 1)) | 340 (((rgb & Int4(0xF800)) >> 8) | ((rgb & Int4(0xE000)) >> 13)); 341 342 s += 4 * sBytes; 343 d += 4 * dBytes; 344 } 345 break; 346 default: 347 ASSERT(false); 348 break; 349 } 350 351 For(, x < width, x++) 352 { 353 switch(state.sourceFormat) 354 { 355 case VK_FORMAT_R8G8B8A8_UNORM: 356 *Pointer<Int>(d) = *Pointer<Int>(s); 357 break; 358 case VK_FORMAT_B8G8R8A8_UNORM: 359 { 360 Int bgra = *Pointer<Int>(s); 361 *Pointer<Int>(d) = ((bgra & Int(0x00FF0000)) >> 16) | 362 ((bgra & Int(0x000000FF)) << 16) | 363 (bgra & Int(0xFF00FF00)); 364 } 365 break; 366 case VK_FORMAT_R16G16B16A16_UNORM: 367 { 368 Short4 c = *Pointer<UShort4>(s) >> 8; 369 370 *Pointer<Int>(d) = Int(As<Int2>(PackUnsigned(c, c))); 371 } 372 break; 373 case VK_FORMAT_R5G6B5_UNORM_PACK16: 374 { 375 Int rgb = Int(*Pointer<Short>(s)); 376 377 *Pointer<Int>(d) = 0xFF000000 | 378 ((rgb & 0x001F) << 19) | ((rgb & 0x001C) << 14) | 379 ((rgb & 0x07E0) << 5) | ((rgb & 0x0600) >> 1) | 380 ((rgb & 0xF800) >> 8) | ((rgb & 0xE000) >> 13); 381 } 382 break; 383 default: 384 ASSERT(false); 385 break; 386 } 387 388 s += sBytes; 389 d += dBytes; 390 } 391 } 392 break; 393 case VK_FORMAT_R5G6B5_UNORM_PACK16: 394 { 395 For(Int x = x0, x < width, x++) 396 { 397 switch(state.sourceFormat) 398 { 399 case VK_FORMAT_B8G8R8A8_UNORM: 400 { 401 Int c = *Pointer<Int>(s); 402 403 *Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 | 404 (c & 0x0000FC00) >> 5 | 405 (c & 0x000000F8) >> 3); 406 } 407 break; 408 case VK_FORMAT_R8G8B8A8_UNORM: 409 { 410 Int c = *Pointer<Int>(s); 411 412 *Pointer<Short>(d) = Short((c & 0x00F80000) >> 19 | 413 (c & 0x0000FC00) >> 5 | 414 (c & 0x000000F8) << 8); 415 } 416 break; 417 case VK_FORMAT_R16G16B16A16_UNORM: 418 { 419 Short4 cc = *Pointer<UShort4>(s) >> 8; 420 Int c = Int(As<Int2>(PackUnsigned(cc, cc))); 421 422 *Pointer<Short>(d) = Short((c & 0x00F80000) >> 19 | 423 (c & 0x0000FC00) >> 5 | 424 (c & 0x000000F8) << 8); 425 } 426 break; 427 case VK_FORMAT_R5G6B5_UNORM_PACK16: 428 *Pointer<Short>(d) = *Pointer<Short>(s); 429 break; 430 default: 431 ASSERT(false); 432 break; 433 } 434 435 s += sBytes; 436 d += dBytes; 437 } 438 } 439 break; 440 default: 441 ASSERT(false); 442 break; 443 } 444 } 445 446 if(state.cursorWidth > 0 && state.cursorHeight > 0) 447 { 448 Int x0 = *Pointer<Int>(cursor + OFFSET(Cursor,x)); 449 Int y0 = *Pointer<Int>(cursor + OFFSET(Cursor,y)); 450 451 For(Int y1 = 0, y1 < state.cursorHeight, y1++) 452 { 453 Int y = y0 + y1; 454 455 If(y >= 0 && y < height) 456 { 457 Pointer<Byte> d = dst + y * dStride + x0 * dBytes; 458 Pointer<Byte> s = src + y * sStride + x0 * sBytes; 459 Pointer<Byte> c = *Pointer<Pointer<Byte>>(cursor + OFFSET(Cursor,image)) + y1 * state.cursorWidth * 4; 460 461 For(Int x1 = 0, x1 < state.cursorWidth, x1++) 462 { 463 Int x = x0 + x1; 464 465 If(x >= 0 && x < width) 466 { 467 blend(state, d, s, c); 468 } 469 470 c += 4; 471 s += sBytes; 472 d += dBytes; 473 } 474 } 475 } 476 } 477 } 478 479 return function("FrameBuffer"); 480 } 481 482 void FrameBuffer::blend(const BlitState &state, const Pointer<Byte> &d, const Pointer<Byte> &s, const Pointer<Byte> &c) 483 { 484 Short4 c1; 485 Short4 c2; 486 487 c1 = Unpack(*Pointer<Byte4>(c)); 488 489 switch(state.sourceFormat) 490 { 491 case VK_FORMAT_B8G8R8A8_UNORM: 492 c2 = Unpack(*Pointer<Byte4>(s)); 493 break; 494 case VK_FORMAT_R8G8B8A8_UNORM: 495 c2 = Swizzle(Unpack(*Pointer<Byte4>(s)), 0xC6); 496 break; 497 case VK_FORMAT_R16G16B16A16_UNORM: 498 c2 = Swizzle(*Pointer<Short4>(s), 0xC6); 499 break; 500 case VK_FORMAT_R5G6B5_UNORM_PACK16: 501 { 502 Int rgb(*Pointer<Short>(s)); 503 rgb = 0xFF000000 | 504 ((rgb & 0xF800) << 8) | ((rgb & 0xE01F) << 3) | 505 ((rgb & 0x07E0) << 5) | ((rgb & 0x0600) >> 1) | 506 ((rgb & 0x001C) >> 2); 507 c2 = Unpack(As<Byte4>(rgb)); 508 } 509 break; 510 default: 511 ASSERT(false); 512 break; 513 } 514 515 c1 = As<Short4>(As<UShort4>(c1) >> 9); 516 c2 = As<Short4>(As<UShort4>(c2) >> 9); 517 518 Short4 alpha = Swizzle(c1, 0xFF) & Short4(0xFFFFu, 0xFFFFu, 0xFFFFu, 0x0000); 519 520 c1 = (c1 - c2) * alpha; 521 c1 = c1 >> 7; 522 c1 = c1 + c2; 523 c1 = c1 + c1; 524 525 switch(state.destFormat) 526 { 527 case VK_FORMAT_B8G8R8A8_UNORM: 528 *Pointer<Byte4>(d) = Byte4(PackUnsigned(c1, c1)); 529 break; 530 case VK_FORMAT_R8G8B8A8_UNORM: 531 case VK_FORMAT_R8G8B8A8_SRGB: 532 { 533 c1 = Swizzle(c1, 0xC6); 534 535 *Pointer<Byte4>(d) = Byte4(PackUnsigned(c1, c1)); 536 } 537 break; 538 case VK_FORMAT_R5G6B5_UNORM_PACK16: 539 { 540 Int c = Int(As<Int2>(PackUnsigned(c1, c1))); 541 542 *Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 | 543 (c & 0x0000FC00) >> 5 | 544 (c & 0x000000F8) >> 3); 545 } 546 break; 547 default: 548 ASSERT(false); 549 break; 550 } 551 } 552 553 void FrameBuffer::threadFunction(void *parameters) 554 { 555 FrameBuffer *frameBuffer = *static_cast<FrameBuffer**>(parameters); 556 557 while(!frameBuffer->terminate) 558 { 559 frameBuffer->blitEvent.wait(); 560 561 if(!frameBuffer->terminate) 562 { 563 frameBuffer->copyLocked(); 564 565 frameBuffer->syncEvent.signal(); 566 } 567 } 568 } 569 } 570