private void drawSatValPanel(Canvas canvas)
        {
            /*
             * Draw time for this code without using bitmap cache and hardware acceleration was around 20ms.
             * Now with the bitmap cache and the ability to use hardware acceleration we are down at 1ms as long as the hue isn't changed.
             * If the hue is changed we the sat/val rectangle will be rendered in software and it takes around 10ms.
             * But since the rest of the view will be rendered in hardware the performance gain is big!
             */

            RectF rect = mSatValRect;

            if (BORDER_WIDTH_PX > 0)
            {
                mBorderPaint.Color = new Color((int)mBorderColor);
                canvas.DrawRect(mDrawingRect.Left, mDrawingRect.Top, rect.Right + BORDER_WIDTH_PX, rect.Bottom + BORDER_WIDTH_PX, mBorderPaint);
            }

            if (mValShader == null)
            {
                //Black gradient has either not been created or the view has been resized.
                uint startColor = 0xFFFFFFFF;
                uint endColor = 0xFF000000;
                mValShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom,
                        new Color((int)startColor), new Color((int)endColor), Shader.TileMode.Clamp);
            }

            //If the hue has changed we need to recreate the cache.
            if (mSatValBackgroundCache == null || mSatValBackgroundCache.value != mHue)
            {

                if (mSatValBackgroundCache == null)
                {
                    mSatValBackgroundCache = new BitmapCache();
                }

                //We create our bitmap in the cache if it doesn't exist.
                if (mSatValBackgroundCache.bitmap == null)
                {
                    mSatValBackgroundCache.bitmap = Bitmap.CreateBitmap((int)rect.Width(), (int)rect.Height(), Bitmap.Config.Argb8888);
                }

                //We create the canvas once so we can draw on our bitmap and the hold on to it.
                if (mSatValBackgroundCache.canvas == null)
                {
                    mSatValBackgroundCache.canvas = new Canvas(mSatValBackgroundCache.bitmap);
                }

                int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f });
                uint startColor = 0xFFFFFFFF;
                mSatShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top,
                        new Color((int)startColor), new Color(rgb), Shader.TileMode.Clamp);

                ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.Multiply);
                mSatValPaint.SetShader(mShader);

                //ly we draw on our canvas, the result will be stored in our bitmap which is already in the cache.
                //Since this is drawn on a canvas not rendered on screen it will automatically not be using the hardware acceleration.
                //And this was the code that wasn't supported by hardware acceleration which mean there is no need to turn it of anymore.
                //The rest of the view will still be hardware accelerated!!
                mSatValBackgroundCache.canvas.DrawRect(0, 0, mSatValBackgroundCache.bitmap.Width, mSatValBackgroundCache.bitmap.Height, mSatValPaint);

                //We set the hue value in our cache to which hue it was drawn with,
                //then we know that if it hasn't changed we can reuse our cached bitmap.
                mSatValBackgroundCache.value = mHue;

            }

            //We draw our bitmap from the cached, if the hue has changed
            //then it was just recreated otherwise the old one will be used.
            canvas.DrawBitmap(mSatValBackgroundCache.bitmap, null, rect, null);

            Point p = satValToPoint(mSat, mVal);

            mSatValTrackerPaint.Color = Color.Black;
            canvas.DrawCircle(p.X, p.Y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);

            mSatValTrackerPaint.Color = Color.LightGray;
            canvas.DrawCircle(p.X, p.Y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
        }
        private void DrawSatValPanel(Canvas canvas)
        {
            #if __ANDROID_11__
            if (Android.OS.Build.VERSION.SdkInt > Android.OS.BuildVersionCodes.Honeycomb)
            {
                RootView.SetLayerType(LayerType.Software, null);
            }
            #endif
            
            var rect = _satValRect;

		    if(BorderWidthPx > 0){
			    _borderPaint.Color = _borderColor;
                canvas.DrawRect(_drawingRect.Left, _drawingRect.Top, rect.Right + BorderWidthPx, rect.Bottom + BorderWidthPx, _borderPaint);
		    }

		    if (_valShader == null) {
                _valShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom,
					    Color.Argb(255,255,255,255), Color.Argb(255,0,0,0), Shader.TileMode.Clamp);
		    }

		    var rgb = ColorUtils.ColorFromHSV(_hue/360f,1f,1f);

		    using (_satShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top,
				    Color.Argb(255,255,255,255), rgb, Shader.TileMode.Clamp))
            {
		        var mShader = new ComposeShader(_valShader, _satShader, PorterDuff.Mode.Multiply);
		        _satValPaint.SetShader(mShader);

		        canvas.DrawRect(rect, _satValPaint);
            }
		    var p = SatValToPoint(_sat, _val);

		    _satValTrackerPaint.Color = Color.Argb(255,0,0,0);
		    canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius - 1f * _density, _satValTrackerPaint);

		    _satValTrackerPaint.Color = Color.Argb(255, 221, 221, 221);
            canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius, _satValTrackerPaint);    
	    }
        private Bitmap createColorWheelBitmap(int width, int height)
        {

            Bitmap bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);

            int colorCount = 12;
            int colorAngleStep = 360 / 12;
            int[] colors = new int[colorCount + 1];
            float[] hsv = new float[] { 0f, 1f, 1f };
            for (int i = 0; i < colors.Length; i++)
            {
                hsv[0] = (i * colorAngleStep + 180) % 360;
                colors[i] = Color.HSVToColor(hsv);
            }
            colors[colorCount] = colors[0];

            SweepGradient sweepGradient = new SweepGradient(width / 2, height / 2, colors, null);

            RadialGradient radialGradient = new RadialGradient(width / 2, height / 2, colorWheelRadius, new Color(0xFFFFFF), new Color(0x00FFFFFF), Shader.TileMode.Clamp);
            ComposeShader composeShader = new ComposeShader(sweepGradient, radialGradient, PorterDuff.Mode.SrcOver);

            colorWheelPaint.SetShader(composeShader);

            Canvas canvas = new Canvas(bitmap);
            canvas.DrawCircle(width / 2, height / 2, colorWheelRadius, colorWheelPaint);

            return bitmap;

        }
        private void DrawSatValPanel(Canvas canvas)
        {
		    var rect = _satValRect;

		    if(BorderWidthPx > 0){
			    _borderPaint.Color = _borderColor;
                canvas.DrawRect(_drawingRect.Left, _drawingRect.Top, rect.Right + BorderWidthPx, rect.Bottom + BorderWidthPx, _borderPaint);
		    }

		    if (_valShader == null) {
                _valShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom,
					    Color.Argb(255,255,255,255), Color.Argb(255,0,0,0), Shader.TileMode.Clamp);
		    }

		    var rgb = ColorUtils.ColorFromHSV(_hue/360f,1f,1f);

		    using (_satShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top,
				    Color.Argb(255,255,255,255), rgb, Shader.TileMode.Clamp))
            {
		        var mShader = new ComposeShader(_valShader, _satShader, PorterDuff.Mode.Multiply);
		        _satValPaint.SetShader(mShader);

		        canvas.DrawRect(rect, _satValPaint);
            }
		    var p = SatValToPoint(_sat, _val);

		    _satValTrackerPaint.Color = Color.Argb(255,0,0,0);
		    canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius - 1f * _density, _satValTrackerPaint);

		    _satValTrackerPaint.Color = Color.Argb(255, 221, 221, 221);
            canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius, _satValTrackerPaint);    
	    }