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 "FrameBufferOSX.hpp" 16 17#include "Common/Debug.hpp" 18 19#include <EGL/egl.h> 20#import <QuartzCore/QuartzCore.h> 21 22namespace sw { 23 24 FrameBufferOSX::FrameBufferOSX(CALayer* layer, int width, int height) 25 : FrameBuffer(width, height, false, false), width(width), height(height), 26 layer(layer), buffer(nullptr), provider(nullptr), currentImage(nullptr) 27 { 28 format = sw::FORMAT_X8B8G8R8; 29 int bufferSize = width * height * 4 * sizeof(uint8_t); 30 buffer = new uint8_t[bufferSize]; 31 provider = CGDataProviderCreateWithData(nullptr, buffer, bufferSize, nullptr); 32 colorspace = CGColorSpaceCreateDeviceRGB(); 33 } 34 35 FrameBufferOSX::~FrameBufferOSX() 36 { 37 //[CATransaction begin]; 38 //[layer setContents:nullptr]; 39 //[CATransaction commit]; 40 41 CGImageRelease(currentImage); 42 CGColorSpaceRelease(colorspace); 43 CGDataProviderRelease(provider); 44 45 delete[] buffer; 46 } 47 48 void FrameBufferOSX::flip(sw::Surface *source) 49 { 50 blit(source, nullptr, nullptr); 51 } 52 53 void FrameBufferOSX::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) 54 { 55 copy(source); 56 57 int bytesPerRow = width * 4 * sizeof(uint8_t); 58 CGImageRef image = CGImageCreate(width, height, 8, 32, bytesPerRow, colorspace, kCGBitmapByteOrder32Big, provider, nullptr, false, kCGRenderingIntentDefault); 59 60 [CATransaction begin]; 61 [layer setContents:(id)image]; 62 [CATransaction commit]; 63 [CATransaction flush]; 64 65 if(currentImage) 66 { 67 CGImageRelease(currentImage); 68 } 69 currentImage = image; 70 } 71 72 void *FrameBufferOSX::lock() 73 { 74 stride = width * 4 * sizeof(uint8_t); 75 framebuffer = buffer; 76 return framebuffer; 77 }; 78 79 void FrameBufferOSX::unlock() 80 { 81 framebuffer = nullptr; 82 }; 83} 84 85sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType nativeWindow, int width, int height) 86{ 87 NSObject *window = reinterpret_cast<NSObject*>(nativeWindow); 88 CALayer *layer = nullptr; 89 90 if([window isKindOfClass:[NSView class]]) 91 { 92 NSView *view = reinterpret_cast<NSView*>(window); 93 [view setWantsLayer:YES]; 94 layer = [view layer]; 95 } 96 else if([window isKindOfClass:[CALayer class]]) 97 { 98 layer = reinterpret_cast<CALayer*>(window); 99 } 100 else ASSERT(0); 101 102 return new sw::FrameBufferOSX(layer, width, height); 103} 104