Home | History | Annotate | Download | only in WSI
      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 "System/Debug.hpp"
     18 
     19 #include <EGL/egl.h>
     20 #import <QuartzCore/QuartzCore.h>
     21 
     22 namespace 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 
     85 sw::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