blob: 6d58ae7e46918e26ab3a69fa145c19f4e56e0622 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// 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
Corentin Wallez27654c22015-12-09 15:22:08 -050015#include "FrameBufferOSX.hpp"
16
Corentin Wallezcd0a4572015-12-10 15:59:28 -050017#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 {
Nicolas Capense5a96372017-08-11 15:14:25 -040028 format = sw::FORMAT_X8B8G8R8;
Corentin Wallezcd0a4572015-12-10 15:59:28 -050029 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -040044
Corentin Wallezcd0a4572015-12-10 15:59:28 -050045 delete[] buffer;
46 }
47
Nicolas Capens241f7892015-12-30 23:40:45 -050048 void FrameBufferOSX::flip(sw::Surface *source)
Corentin Wallez27654c22015-12-09 15:22:08 -050049 {
Nicolas Capens241f7892015-12-30 23:40:45 -050050 blit(source, nullptr, nullptr);
Corentin Wallez27654c22015-12-09 15:22:08 -050051 }
Corentin Wallezcd0a4572015-12-10 15:59:28 -050052
Nicolas Capens241f7892015-12-30 23:40:45 -050053 void FrameBufferOSX::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
Corentin Wallezcd0a4572015-12-10 15:59:28 -050054 {
Nicolas Capens241f7892015-12-30 23:40:45 -050055 copy(source);
Corentin Wallezcd0a4572015-12-10 15:59:28 -050056
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);
Nicolas Capense5a96372017-08-11 15:14:25 -040075 framebuffer = buffer;
76 return framebuffer;
Corentin Wallezcd0a4572015-12-10 15:59:28 -050077 };
Nicolas Capens0bac2852016-05-07 06:09:58 -040078
Corentin Wallezcd0a4572015-12-10 15:59:28 -050079 void FrameBufferOSX::unlock()
80 {
Nicolas Capense5a96372017-08-11 15:14:25 -040081 framebuffer = nullptr;
Corentin Wallezcd0a4572015-12-10 15:59:28 -050082 };
Corentin Wallez27654c22015-12-09 15:22:08 -050083}
84
Corentin Wallezcd0a4572015-12-10 15:59:28 -050085sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType nativeWindow, int width, int height)
Corentin Wallez27654c22015-12-09 15:22:08 -050086{
Corentin Wallezcd0a4572015-12-10 15:59:28 -050087 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);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400101
Corentin Wallez27654c22015-12-09 15:22:08 -0500102 return new sw::FrameBufferOSX(layer, width, height);
103}